s-maxage
s-maxage is a Cache-Control
directive that sets the freshness lifetime for shared caches — CDNs and
proxies — separately from the browser. Where both are present, shared caches follow
s-maxage and ignore max-age; browsers never look at
s-maxage.
Why two lifetimes?
Because you can purge a CDN, but you can't purge your visitors' browsers. That asymmetry makes different TTLs the right default:
Cache-Control: public, max-age=60, s-maxage=86400
Browsers re-check after a minute — so a correction you publish reaches returning visitors quickly. The CDN keeps the copy for a day, giving you a high hit ratio; when content changes you purge and re-warm, and the long edge TTL costs you nothing in staleness.
CDN-specific variants
Several CDNs add headers that control only their own cache and are stripped before the response goes out:
CDN-Cache-Control— the standardized variant (RFC 9213), respected by Cloudflare and others.Cloudflare-CDN-Cache-Control— Cloudflare only; wins overCDN-Cache-Controlands-maxagethere.Surrogate-Control— Fastly's traditional equivalent.
Precedence (most specific wins): vendor header → CDN-Cache-Control →
s-maxage → max-age. If a cached response seems to ignore your
s-maxage, check whether a CDN rule (e.g. Cloudflare "Edge Cache TTL")
overrides headers entirely.
The catch
s-maxage is a ceiling, not a guarantee: under cache pressure a CDN may
evict your object long before it expires — in
our own measurements, some edge locations lost up to 9% of warmed objects between
hourly passes. A long s-maxage plus scheduled re-warming is what actually
keeps the edge hot. Verify per location with the
cache checker.