Skip to content

fix: shorten /routing/v1 stale windows - #1195

Merged
lidel merged 3 commits into
mainfrom
fix/routing-v1-stale-windows
Jul 27, 2026
Merged

fix: shorten /routing/v1 stale windows#1195
lidel merged 3 commits into
mainfrom
fix/routing-v1-stale-windows

Conversation

@lidel

@lidel lidel commented Jul 24, 2026

Copy link
Copy Markdown
Member

Problem

/routing/v1 responses tell caches they may serve a two day old answer, and CDNs take that literally: two requests for the same CID minutes apart can come back with different providers, or none, and the older one wins until it ages out. The 48h is the Amino DHT provider record expiration, but most of what a response carries is peer addresses, and those come from short-lived sources such as relay reservations. Two days of stale hands clients relay addrs that died long ago.

Fix

  • stale-while-revalidate drops to 10 minutes with results, 1 minute without. It is served while the origin is healthy, so it only needs to cover a background refresh.
  • stale-if-error keeps 48h with results, 1 hour for empty ones. It only fires when the origin is failing, where a stale answer beats no answer.
  • max-age is unchanged at 300s / 15s.

Hot CIDs still revalidate in the background, so this costs no extra lookups there. The spec leaves the value open1; this reads "maximum cache window" as the address lifetime rather than the record lifetime.

Footnotes

  1. Delegated Routing V1, section 4.1.4: max-age SHOULD be shorter for empty results, and max-ttl SHOULD be "set to the maximum cache window of the underlying routing system". Same wording in 5.1.4 and 7.1.3.

Caches were told they may serve a two day old answer while the origin is
healthy. The 48h window matches Amino DHT provider record expiration,
but responses mostly carry peer addresses drawn from short-lived sources
such as relay reservations, so clients kept getting addrs that stopped
working long ago.

- stale-while-revalidate: 10m with results, 1m without, enough to cover
  a background refresh
- stale-if-error: 48h with results, 1h without, it only applies when the
  origin is failing
- max-age unchanged
@lidel
lidel requested a review from achingbrain July 24, 2026 11:21
@lidel
lidel marked this pull request as ready for review July 24, 2026 11:22
@lidel
lidel requested a review from a team as a code owner July 24, 2026 11:22
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 63.84%. Comparing base (b5c1df7) to head (aa8c1c5).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
routing/http/server/server.go 92.85% 1 Missing ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1195      +/-   ##
==========================================
- Coverage   63.85%   63.84%   -0.01%     
==========================================
  Files         269      269              
  Lines       27139    27144       +5     
==========================================
+ Hits        17330    17331       +1     
- Misses       8094     8099       +5     
+ Partials     1715     1714       -1     
Files with missing lines Coverage Δ
routing/http/server/server.go 79.34% <92.85%> (+0.24%) ⬆️

... and 9 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

lidel added 2 commits July 27, 2026 13:43
Rewrite the four unreleased entries in shorter sentences with an
active voice, and name the actor where the passive hid it.

- gateway: split the long CAR truncation and traversal-depth entries
- bitswap: state both IPv6 parse outcomes and add the missing PR link
- routing/http/server: lead with why days-long stale windows hurt
@lidel
lidel merged commit 1c8cf64 into main Jul 27, 2026
26 checks passed
lidel added a commit to ipfs/someguy that referenced this pull request Jul 27, 2026
Picks up the shorter /routing/v1 stale windows from ipfs/boxo#1195, so
caches stop serving a two-day-old answer while someguy is healthy.

go-libp2p-kad-dht v0.42.0 dropped the context argument from its
constructors. Cancelling the context that built a DHT no longer stops
it, so someguy lost its only shutdown path and had to grow an explicit
one, the same way kubo closes both clients on stop.

- drop ctx from dht.New, and from newBundledDHT which no longer used it
- add bundledDHT.Close and call it on shutdown, covering the standard
  client too via io.Closer
- update the Cache-Control assertions the new stale windows changed
- restore the changelog section order broken in #169
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant