HTTP cache freshness and the scope of stale-while-revalidate

RFC 9111 defines HTTP cache storage, reuse, and validation. max-age contributes to a response’s freshness lifetime; shared caches can use s-maxage. ETag and Last-Modified support conditional validation of stale responses. The stale-while-revalidate directive is an extension defined by RFC 5861, not RFC 9111. It allows a cache to serve a stale response while attempting background validation during the stated window, but it does not require every cache to support the extension or behave identically.

Expert perspective: Fastly cache behavior and its conditions

Fastly’s documentation explains that its cache can serve an eligible stale object while asynchronously revalidating it when the object is cacheable, still present, and the request uses the relevant cache path. The behavior cannot apply if the object has already been evicted or the request is passed to the backend. This is practical guidance for Fastly’s platform. It does not mean every CDN edge guarantees the same refresh behavior or globally coordinated refresh. Sparse traffic may not trigger a validation request during the window at all.

The stale window is a data-age policy

Cache-Control: max-age=300, stale-while-revalidate=60 is an example that treats a response as fresh for 300 seconds and permits stale serving for up to 60 more seconds. That window is a product decision about acceptable data age. Do not apply it indiscriminately to balances, access rights, inventory, or other responses that must remain current. RFC 5861 says a cache serving stale should attempt non-blocking validation, but serving stale is permitted (MAY), and after the window the cache should not continue without other information. stale-if-error is a separate extension for stale responses when an error occurs; it is not the same as background revalidation.

A hypothetical timeline for reading Age

Assume the response Cache-Control: max-age=300, stale-while-revalidate=60 remains cached, the cache supports this extension, and no other directive or local policy (such as must-revalidate or s-maxage) changes the result. Age represents the response's current age. The outcomes below describe what the extension permits; they do not guarantee what every CDN will serve (RFC 9111 §4.2, RFC 5861 §3).

Request AgeAge classificationDecision under these directives
250 secondsFresh, within max-age=300The stored response can be reused without validation.
320 seconds20 seconds stale, within the 60-second SWR windowThe cache may serve stale; if it does, it should attempt non-blocking revalidation.
370 seconds70 seconds stale, beyond the 60-second SWR windowSWR alone no longer permits stale serving. Without another allowance, the request needs validation or a fresh origin response.

stale-while-revalidate=60 does not make the response fresh for 60 more seconds. To determine whether a stale response was actually served at age 320, check Age at the observed hop, the origin revalidation time, and CDN cache logs. RFC 9111 obsoletes the Warning field, so it is not a required validation signal. Separately confirm extension support and any other Cache-Control directives or provider-specific policy.

Shared-cache safety and verification

Check that the shared cache key, including URL, method, and Vary, separates user-specific responses. Apply RFC rules and exceptions for private, no-store, and responses to Authorization requests, and verify that CDN-specific cache rules do not override the intended policy. Responses containing cookies or user-specific tokens should be explicitly separated or bypassed. Test browser and edge support, Age, conditional requests, shielding and purge configuration, and revalidation traffic using real responses and logs. SWR can hide latency, but it does not guarantee lower origin load or always-fresh content.

References