Stale Content
Cached content whose TTL has expired but is still stored. Can be served during origin failures (stale-if-error) or while revalidating (stale-while-revalidate). A resilience tool, not a bug.
Full Explanation
When a cached object's TTL expires, it becomes stale. Normally the cache must revalidate or fetch a fresh copy before serving it. But with the right Cache-Control directives, stale content becomes a powerful resilience mechanism.
stale-while-revalidate lets the cache serve stale content immediately while fetching fresh content in the background. The user gets fast response times, and the cache gets updated for the next request. stale-if-error lets the cache serve stale content when the origin is down or returning errors.
Together, these directives make your site practically unbreakable. Origin goes down? Users see the last known good content instead of a 502. Content expires? Users get the old version instantly while the fresh version loads behind the scenes. The tradeoff is eventual consistency: some users will see slightly outdated content for a brief window.
Examples
# Resilient caching with stale directives
Cache-Control: public, max-age=300, stale-while-revalidate=60, stale-if-error=86400
# Fresh for 5 min, serve stale for 1 min while revalidating,
# serve stale for 24h if origin is down
# Varnish: grace mode
sub vcl_backend_response {
set beresp.grace = 1h;
}
sub vcl_hit {
if (obj.ttl + obj.grace > 0s) {
return (deliver); # Stale but within grace
}
}
# Nginx: proxy_cache_use_stale
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
Frequently Asked Questions
Cached content whose TTL has expired but is still stored. Can be served during origin failures (stale-if-error) or while revalidating (stale-while-revalidate). A resilience tool, not a bug.
# Resilient caching with stale directives
Cache-Control: public, max-age=300, stale-while-revalidate=60, stale-if-error=86400
# Fresh for 5 min, serve stale for 1 min while revalidating,
# serve stale for 24h if origin is down
# Varnish: grace mode
sub vcl_backend_response {
set beresp.grace = 1h;
}
sub vcl_hit {
if (obj.ttl + obj.grace > 0s) {
return (deliver); # Stale but within grace
}
}
# Nginx: proxy_cache_use_stale
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
Related CDN concepts include:
- must-revalidate — Once content becomes stale, the cache must revalidate with the origin before serving it. The …
- stale-if-error — Allows caches to serve stale content when the origin returns an error (5xx) or is …
- stale-while-revalidate — Allows caches to serve stale content immediately while fetching a fresh copy in the background. …
- Cache-Control — The primary HTTP header for controlling caching behavior. Tells browsers, CDNs, and proxies whether to …
- PURGE — Removing cached content from CDN edges before its TTL expires. Can target a single URL, …
- TTL (Time To Live) (TTL) — How long a cached response is considered fresh before it must be revalidated or re-fetched. …