Skip to content

⚡ Cache Header Analyzer

Analyze Cache-Control, ETag, Expires, Vary, Age — with human-readable max-age / s-maxage. Auto-detects major CDNs (Cloudflare, CloudFront, Fastly, Akamai, Vercel).

100% Free No signup Server-side No logs / DB Rate-limited 5 languages Dark mode

⚠️ Requests are made from DevLab servers. Private IP addresses and localhost are not allowed.

📚 Cache-Control Reference

public: Cacheable by any cache including CDN/proxy

private: Browser only (no shared caches)

no-store: Never cache anywhere

no-cache: May cache, but must revalidate every time

max-age=N: Fresh for N seconds

s-maxage=N: max-age applied only to shared caches (CDN)

immutable: No revalidation even on reload — perfect for hashed assets

stale-while-revalidate=N: Serve stale up to N seconds while revalidating in background

stale-if-error=N: Serve stale up to N seconds on origin error

📖 What this check tells you

This check pulls Cache-Control, ETag, Last-Modified, Expires and CDN-specific headers out of the response and breaks the directives down for you. It can only tell you what you are instructing, not what actually got cached. A browser under storage pressure evicts regardless of your instructions, and a CDN may override them with its own rules.

Item What it means How to fix it
No Cache-Control at all Saying nothing does not mean not cached — the cache is free to guess a lifetime (heuristic caching). Where a Last-Modified exists, the common implementation treats roughly 10 % of the time since that date as fresh. For a page last edited a year ago, that is about a month of caching you never asked for. Be explicit on every response. Three patterns cover nearly everything: no-cache for HTML (store it, but revalidate every time), max-age=31536000, immutable for content-hashed assets, and private, no-store for responses containing personal data. Despite the confusing names, no-cache stores and no-store does not.
A long max-age on a mutable file Put a one-year max-age on a fixed name like style.css and existing visitors will not see an update for a year. Worse, a cache already handed to a browser cannot be recalled from the server side: a CDN purge reaches the edge and no further. Use a long TTL only together with a design where the filename changes on update — a content hash in the name, such as app.4f2c1a.css, with the HTML reference rewritten. That makes immutable safe, and even a reload skips revalidation. If a long TTL is already out there, renaming the file and writing off the old one is the only recovery.
public on a personalised response When a page containing a login name or cart contents carries public — or s-maxage — a shared cache stores it and serves it verbatim to the next, different visitor. Showing one user the personal data of another is the worst outcome a caching mistake can produce, and it typically surfaces right after a CDN is introduced. Return Cache-Control: private, no-store on authenticated responses. Vary: Cookie separates them in theory, but it creates an entry per cookie value, so caching effectively stops working and the CDN gains you nothing. Splitting anonymous and authenticated traffic by path or subdomain, and making only the former cacheable, is the more reliable design.

What makes caching dangerous is that a mistake leaves your hands and keeps living. Fixing the configuration cannot recall instructions already distributed, which is why the rule is to start short and extend later when in doubt. Adding stale-while-revalidate lets you serve the old copy while refreshing in the background instead of making someone wait at the moment of expiry, so a short max-age costs nothing in perceived speed. With a CDN, a short max-age for browsers plus a long s-maxage for the edge, refreshed by purge, is the combination that stays manageable.

🔗 Related Tools