HTTP headers · Response, also request directives
Cache-Control
Cache-Control tells browsers and shared caches whether, and for how long, they may store a response.
Key facts
| Type | Response, also request directives |
|---|---|
| Freshness | <code>max-age=600</code> |
| Shared caches | <code>s-maxage</code>, <code>private</code> |
| Never store | <code>no-store</code> |
| Revalidate | <code>no-cache</code> |
| Reuse as-is | <code>immutable</code> |
| Stale reuse | <code>stale-while-revalidate</code> |
| Standard | RFC 9111, RFC 5861 |
The directives that matter
max-age is a relative lifetime in seconds. s-maxage overrides it for shared caches such as CDNs. private forbids shared caching but still allows the browser; no-store forbids storage altogether. no-cache is widely misread: it permits storage but requires revalidation before every reuse.
must-revalidate prevents a cache from serving stale content when the origin cannot be reached. immutable promises the representation will not change during its lifetime, which avoids reload requests for versioned assets.
Choosing a policy
Fingerprinted assets such as app.9f2c1.js can use public, max-age=31536000, immutable. HTML that names those assets should use a short lifetime with revalidation, so a deploy is visible quickly. Authenticated responses should be private, no-store unless the data is safe to keep on disk.
Cache-Control does not delete existing copies. Changing a policy affects future responses, and a CDN may continue to serve what it already stored until its own rules evict it.
Frequently asked questions
What is the difference between no-cache and no-store?
no-cache stores but revalidates before use; no-store does not store the response at all.
Does max-age apply to the browser and the CDN?
max-age applies to all caches. s-maxage applies only to shared caches and takes precedence there.