Caching Headers Explained: Cache-Control and ETag
How HTTP caching directives balance performance against content freshness across browsers, CDNs, and proxies.
Core Concept
HTTP caching headers instruct browsers, CDNs, and proxies how long a response can be reused before it needs to be re-fetched or revalidated.
Well-tuned caching dramatically reduces load times and server load; poorly tuned caching either serves stale content or fails to cache anything useful at all.
Cache-Control Directives
Cache-Control is the primary modern caching header, supporting a range of directives for fine-grained control.
- max-age — how long a response is considered fresh, in seconds
- no-cache — must revalidate before using a cached copy
- no-store — never cache the response at all
- public / private — whether shared caches like CDNs may store it
no-cache Is Misleading
Despite its name, no-cache doesn't prevent caching — it requires revalidation with the server before the cached copy is used.
Validation With ETag and Last-Modified
Validators allow a cache to check whether stored content is still current without re-downloading it entirely.
- ETag — a fingerprint identifying a specific content version
- Last-Modified — timestamp of the most recent content change
- 304 Not Modified — server confirms the cached copy is still valid
Caching Strategy by Content Type
Different types of content warrant meaningfully different caching strategies.
Immutable, versioned assets like fingerprinted JavaScript bundles can be cached extremely aggressively, while dynamic API responses typically need much shorter or no caching at all.
Fingerprinted Assets
Content-hashed filenames let static assets use a near-infinite cache lifetime safely, since any content change produces a new filename automatically.
Common Caching Mistakes
A few recurring patterns cause the majority of real-world caching bugs.
- Caching authenticated or personalized responses as public
- No cache-busting strategy for updated static assets
- Conflicting cache headers set at different layers of the stack
Real-World Implementation
Caching header strategy is central to how modern web performance is achieved at scale.
- CDNs relying on Cache-Control to determine edge caching behavior
- Build tools fingerprinting assets to enable aggressive caching
- APIs using short-lived or no-store caching for dynamic data
Auditing caching headers against actual content behavior — not just checking that headers exist — catches most real-world caching bugs before they reach production.
Common Mistakes to Avoid
A few common mistakes lead to real-world caching bugs.
- Caching a personalized or authenticated response as if it were public.
- Assuming no-cache prevents caching entirely rather than requiring revalidation.
- Applying the same caching strategy uniformly regardless of content type.
- Overlooking ETag inconsistency across a server cluster serving identical content.
- Failing to set a cache-busting strategy for updated static assets.
- Overlooking stale-while-revalidate as a nuanced middle ground between strict and no caching.
- Assuming CDN caching behavior always matches the origin server's configured headers exactly.
- Failing to test caching behavior across multiple cache layers simultaneously.
- Overlooking the immutable directive, which tells browsers a resource will never change.
- Assuming service workers respect standard Cache-Control headers identically to the browser HTTP cache.
- Failing to account for private CDN edge caching layers separate from browser caching.
- Overlooking that browser back/forward cache behavior can differ from standard HTTP caching rules.
Best Practices Checklist
These practices lead to more reliable, effective caching behavior.
- Match caching strategy to content type rather than applying one setting everywhere.
- Use fingerprinted filenames for static assets to enable safe, aggressive caching.
- Explicitly mark personalized or authenticated responses as private or no-store.
- Ensure ETag generation is consistent across all servers in a cluster.
- Test caching behavior directly rather than assuming header configuration works as intended.
- Consider stale-while-revalidate for content that benefits from serving slightly stale data during revalidation.
- Verify CDN-specific caching behavior directly rather than assuming it matches origin headers exactly.
- Test caching behavior end-to-end across browser, CDN, and origin layers together.
- Use the immutable directive for genuinely permanent, fingerprinted assets to skip revalidation entirely.
- Verify service worker caching behavior explicitly rather than assuming it mirrors standard HTTP caching.
- Account for CDN edge caching as a distinct layer from browser-level caching in your strategy.
- Understand back/forward cache behavior separately from standard Cache-Control-driven HTTP caching.
Frequently Asked Questions
Frequently asked questions about HTTP caching headers.
Does no-cache mean a response won't be cached at all?
No — despite the name, it requires revalidation with the server before a cached copy is used, rather than preventing caching outright.
What's a safe caching strategy for static assets?
Fingerprinted, content-hashed filenames let static assets use a near-infinite cache lifetime safely, since any content change produces a new filename.
Why is it risky to cache personalized content as public?
It can leak one user's data to another through a shared cache if the response isn't explicitly marked private or no-store.
What's the difference between ETag and Last-Modified?
ETag is a content fingerprint, while Last-Modified is a timestamp — both let a cache check freshness without re-downloading the full response.
Can inconsistent ETags across servers cause problems?
Yes — if different servers generate different fingerprints for identical content, it can cause unnecessary cache invalidation.
What does stale-while-revalidate actually do?
It lets a cache serve a slightly stale response immediately while revalidating in the background, balancing performance and freshness.
Does a CDN always cache exactly according to origin server headers?
Not always — some CDNs apply their own overriding rules or defaults, making direct verification worthwhile.
Why test caching across multiple layers instead of just one?
Because browser, CDN, and origin caching can interact in unexpected ways that aren't visible when testing any single layer in isolation.
What does the immutable Cache-Control directive do?
It tells the browser a resource will never change during its cache lifetime, letting it skip revalidation entirely even on a refresh.
Do service workers follow standard HTTP caching rules?
Not automatically — service workers implement their own caching logic in code, which needs to be explicitly aligned with HTTP header intentions.
Is back/forward cache the same as standard HTTP caching?
No — it's a distinct browser mechanism with its own rules, which can behave differently than what Cache-Control headers alone would suggest.
Check Caching Headers
Run an HTTP header analysis to see the caching configuration for any URL.
Launch Tool →