no-cache vs no-store — The Cache-Control Difference That Trips Everyone Up
Updated April 2026
no-cache stores the response in cache but requires revalidation before every use — the browser still sends a request each time. no-store prevents storage entirely — nothing is written to any cache and every request goes directly to origin. Use no-store for sensitive data; no-cache for frequently updated content.
no-cache does not mean "do not cache". It means "cache it, but revalidate before every serve". This single misunderstanding causes countless bugs in production.
Cache-Control: no-cache on sensitive endpoints thinking nothing will be stored. The response is still stored in both browser and CDN caches. Only no-store prevents storage.
The exact difference
| Directive | Stored in cache? | Served without checking origin? | Use for |
|---|---|---|---|
no-cache | Yes | No — must revalidate every time | HTML pages, frequently updated content |
no-store | Never | N/A — nothing stored | Sensitive data, authenticated responses |
How no-cache works
The browser stores the response. On every subsequent request it sends a conditional request to the origin — either If-None-Match (ETag) or If-Modified-Since. If the content has not changed, the origin returns 304 Not Modified with no body and the browser uses the cached copy. If it has changed, the origin returns the new content.
Result: always fresh content, but bandwidth saved when content has not changed. The HTTP round-trip still happens every time.
# Nginx — HTML pages add_header Cache-Control "no-cache" always;
How no-store works
Nothing is written to any cache — not the browser cache, not the CDN, not any intermediate proxy. Every request goes all the way to the origin and returns the full response body.
Result: no caching at all. Maximum freshness, maximum origin load.
# Nginx — authenticated API responses add_header Cache-Control "no-store" always;
When to use each
| Scenario | Directive | Why |
|---|---|---|
| HTML pages (logged-out) | no-cache | Content changes often, but you want fast 304 responses when it hasn't |
| HTML pages (logged-in) | no-store, private | User-specific content must not be cached by CDN |
| Session tokens, auth cookies | no-store | Never store credentials anywhere |
| Public API (real-time data) | no-cache | Allows conditional requests to reduce bandwidth |
| Private API (user data) | no-store | Never cache user-specific responses |
| Payment/checkout pages | no-store | Financial data must never be cached |
The private directive — often confused with these two
private means the browser can cache the response but CDNs must not. It is different from both no-cache and no-store:
private— browser caches, CDN does not. Subsequent browser requests use cache without revalidation (until max-age expires).no-cache— both browser and CDN store it, but must revalidate every time.no-store— nobody stores anything.
# Private user dashboard — browser caches, CDN does not Cache-Control: private, max-age=300 # Sensitive data — nothing stored anywhere Cache-Control: no-store # Public page — store everywhere but always revalidate Cache-Control: no-cache
Combining directives
You will often see combinations like no-cache, no-store, must-revalidate. This is redundant but not harmful — it was historically used for maximum compatibility with HTTP/1.0 caches that did not understand all directives. For modern infrastructure, no-store alone is sufficient.
curl -sI https://yoursite.com/api/endpoint | grep -i cache to see the exact Cache-Control header your server returns.