5 Cache-Control Directives Worth Knowing
Understanding max-age, s-maxage, no-cache, no-store, and stale-while-revalidate — how HTTP caching headers control browser and CDN behavior.

The Cache-Control header controls how browsers and CDNs cache HTTP responses. It's powerful — but also confusing if you don't know what each directive actually does.
Here are five Cache-Control directives worth understanding, explained in plain English. We'll cover how they work, when to use them, and what traps to avoid.
1. max-age — Freshness Lifetime in Seconds
What it does:
max-age tells caches how long a response can be reused without checking with the origin server. The value is in seconds.
Cache-Control: max-age=3600
This says: "You can reuse this response for up to 3600 seconds (1 hour) without asking me again."
Applies to both browser and CDN:
max-age applies to both private caches (your browser) and shared caches (CDNs, proxies). If you want different behavior for each, see s-maxage below.
Age header subtracts elapsed time:
If a CDN has already stored the response for 600 seconds, the browser sees:
Cache-Control: max-age=3600
Age: 600
The browser knows the response has 3000 seconds of freshness left (3600 - 600).
When to use it:
Use max-age for static assets (CSS, JavaScript, images) that change infrequently. Longer values reduce origin requests; shorter values keep content fresher.
Related: What Is Caching? explains the basics of HTTP caching.
2. s-maxage — Shared-Cache Override
What it does:
s-maxage (shared max-age) overrides max-age and Expires for shared caches only — like CDNs and proxies. Private caches (browsers) ignore it.
Cache-Control: max-age=60, s-maxage=3600
This means:
Why this matters:
You might want CDNs to cache aggressively (to reduce origin load) while keeping browser caches short (so users see updates sooner). s-maxage lets you control each independently.
Implies proxy-revalidate semantics:
According to RFC 9111, s-maxage implies that shared caches should not serve stale responses, even if stale-while-revalidate is also set. CDN behavior varies — some honor stale-while-revalidate anyway, some don't. Check your CDN's documentation before relying on this.
Private vs public consideration:
If your response is personalized (user-specific data), use Cache-Control: private to prevent CDNs from caching it at all. private means only the browser cache can store it. public explicitly allows shared caches, but is usually not needed unless you're overriding default behavior for authenticated responses.
Related: What Is a CDN? explains how CDNs cache content.
3. no-cache — Must Revalidate Before Reuse
What it does:
Despite the name, no-cache does NOT mean "don't cache." It means: you can store this response, but you must check with the origin server before reusing it.
Cache-Control: no-cache
How revalidation works:
When the cache needs to serve the response again, it sends a conditional request to the origin:
GET /resource HTTP/1.1
If-None-Match: "etag-value"
If the resource hasn't changed, the server responds with 304 Not Modified — no body, just headers. The cache then serves the stored response. This saves bandwidth compared to re-downloading the entire response.
The misleading name:
The name no-cache confuses people. If you want to prevent caching entirely, use no-store (see below).
From MDN:
> Note that no-cache does not mean "don't cache". no-cache allows caches to store a response but requires them to revalidate it before reuse.
When to use it:
Use no-cache when content must be fresh but bandwidth matters. Pair it with ETag or Last-Modified so revalidation can avoid re-sending unchanged content.
Related: no-cache vs no-store: What's the Difference? goes deeper into these two directives.
4. no-store — Must Not Store the Response
What it does:
no-store tells caches — private and shared — that they must not store the request or response at all. No caching, no storage, period.
Cache-Control: no-store
When to use it:
Use no-store for sensitive content: financial data, private user information, authentication tokens. If storage itself must be avoided, no-store is the right directive.
Not a privacy guarantee:
no-store is a request to well-behaved caches. Malicious or misconfigured caches might ignore it. Always combine with HTTPS and proper authentication for real privacy. From RFC 9111:
> The no-store directive is not a reliable mechanism for ensuring privacy or security.
Trade-offs:
Every request fetches the full response from the origin — no bandwidth savings, no back/forward cache benefits. Use no-store only when necessary.
Related: HTTP vs HTTPS: What Actually Changes covers security and caching headers.
5. stale-while-revalidate — Serve Stale While Updating
What it does:
stale-while-revalidate allows caches to serve a stale (expired) response immediately while fetching a fresh copy in the background. The value is in seconds.
Cache-Control: max-age=3600, stale-while-revalidate=86400
This means:
How it works:
Why this matters:
Users get instant responses even if the cache is stale. The next request will be fresh. This balances speed and freshness.
CDN support varies:
Not all CDNs support stale-while-revalidate behavior. Some CDNs that do:
Check your CDN's documentation. Don't assume it works everywhere.
Defined in RFC 5861.
Related: CDN Edge Cache Explained covers how CDN caching works.
Quick Reference
Here's a summary of the five directives:
| Directive | Meaning | Use Case |
|-----------|---------|----------|
| max-age | Fresh for N seconds (browser + CDN) | Static assets with predictable lifetime |
| s-maxage | Fresh for N seconds (CDN only, overrides max-age) | Aggressive CDN caching, shorter browser cache |
| no-cache | Store but revalidate before reuse | Content that must be fresh but supports 304 |
| no-store | Do not store at all | Sensitive data (tokens, private info) |
| stale-while-revalidate | Serve stale for N extra seconds while updating | Fast responses + background freshness |
The Takeaway
Cache-Control directives give you fine-grained control over how browsers and CDNs cache your content. Understanding max-age, s-maxage, no-cache, no-store, and stale-while-revalidate helps you balance speed, freshness, and security.
The key traps to avoid:
For most cases, max-age with appropriate values is enough. Use the others when you need finer control.
Related Reading:
*This post is part of Hacking Bits, where we explain how everyday technology works — one bit at a time.*
Related Posts
7 Things Your Browser Does Before a Page Loads
From DNS lookup to rendering pixels — here's the hidden work your browser does in milliseconds every time you hit Enter.
no-cache vs no-store: What's the Difference?
Cache-Control: no-cache doesn't mean 'don't cache'. Here's what no-cache and no-store actually do, when to use each, and why the names are misleading.
Checklist: Do You Actually Need a CDN?
A practical checklist to understand what CDNs do, what they cache, when they help, and whether your site needs one.