A hit sends the full max-age=ttl and no Age. An entry stored at t=0 with ttl=60 and served at t=59 is fresh downstream until t=119, so after invalidate() a browser or CDN can keep serving the old response for almost twice the ttl (RFC 9111 §4.2.3, §5.1).
Proposal
Store stored_at in CacheEntry (optional, like status_code) and emit Age on hits and cached-ETag 304s, or lower max-age to the remaining ttl.
A hit sends the full
max-age=ttland noAge. An entry stored at t=0 with ttl=60 and served at t=59 is fresh downstream until t=119, so afterinvalidate()a browser or CDN can keep serving the old response for almost twice the ttl (RFC 9111 §4.2.3, §5.1).Proposal
Store
stored_atinCacheEntry(optional, likestatus_code) and emitAgeon hits and cached-ETag 304s, or lowermax-ageto the remaining ttl.