โ† All docs  ยท  Home

ADR 0012 โ€” HTTP cache freshness + validators between collection and feedback servers

Context

The collection server aggregates a URI's feedback by fanning out to every registered feedback server on each /index. The first cut was already polite โ€” it cached per (server, uri) and revalidated with If-None-Match, so a repeat query cost a cheap 304. But a 304 is still a round-trip per upstream per query: under steady polling that is a lot of requests that only ever say "nothing changed".

HTTP already solves this with two distinct mechanisms we were not using:

Decision

Implement both, end to end.

Feedback server (origin). build_page now emits:

It also honors conditional requests per RFC 7232 precedence: If-None-Match first (ETag), then If-Modified-Since (304 when the page's Last-Modified is not newer than the client's date). HTTP-date handling is a tiny local httpdate module (IMF-fixdate only โ€” the form a sender must produce).

Collection server (cache). The per-(server, uri) entry gains last_modified and a fresh_until: Instant deadline parsed from the upstream max-age. On fetch:

  1. Fresh โ‡’ reuse the cached items with no upstream request and no rate budget spent (counted as a cacheHits metric).
  2. Stale โ‡’ revalidate, sending both validators we hold (If-None-Match + If-Modified-Since); a 304 refreshes fresh_until from the response.
  3. A 200 restocks items + validators + freshness; Cache-Control: no-store suppresses caching.

Why these specifics

Consequences