Cache-Control
The master switch for caching: how long a response can be reused, whether shared caches may store it, and when it must be revalidated — with real security implications.
What it is
Cache-Control (RFC 9111) is the primary header for controlling caching behavior in browsers, CDNs and proxies. It decides whether a response can be stored, by whom, for how long, and whether it must be revalidated before reuse. Getting it wrong ranges from wasted bandwidth to caching a private, authenticated response in a shared cache where another user can retrieve it.
Key directives
- max-age=<sec>
- How long the response is fresh, in seconds.
- s-maxage=<sec>
- Overrides max-age for shared caches (CDNs/proxies) only.
- no-cache
- May be stored, but must revalidate with the origin before every reuse.
- no-store
- Must not be stored anywhere. Use for sensitive, user-specific responses.
- private
- May be cached by the browser but NOT by shared caches. Use for authenticated pages.
- public
- May be cached by any cache, even if the request had Authorization.
- immutable
- The response will never change during its freshness lifetime, so the browser skips revalidation on reload.
- stale-while-revalidate=<sec>
- Serve stale content while revalidating in the background.
- must-revalidate
- Once stale, the cache must revalidate and not serve a stale copy on error.
HTTP RESPONSE HEADERS
# Long-lived, fingerprinted static asset
Cache-Control: public, max-age=31536000, immutable
# Authenticated HTML page
Cache-Control: private, no-cache
# Sensitive response (never store)
Cache-Control: no-storeWhy it matters
- Correct caching of fingerprinted assets (
immutable, one-yearmax-age) is one of the biggest front-end performance wins available. private/no-storeon authenticated responses prevents a shared cache or CDN from serving one user's data to another — a real, common breach vector.- Cache directives interact with the
Varyheader; mis-set caching can serve the wrong language, encoding or auth state.
Common mistakes
- Marking an authenticated page
public(or omittingprivate), letting a CDN cache and serve user-specific data to others. - Using
no-cachewhen you meanno-store—no-cachestill stores the response, it just revalidates it. - Caching HTML with a long
max-ageand no fingerprinting, so users get stale pages after a deploy. - Setting
immutableon content that actually changes, causing users to see outdated files until a hard reload.
How WebInspect checks this
- WebInspect parses
Cache-Controland reports freshness lifetime, shared-cache eligibility and revalidation behavior. - It flags authenticated or personalized responses that are cacheable by shared caches (missing
private/no-store). - It highlights static assets that lack long-lived caching and could be served with
immutablefor a performance gain.