Decode & Debug Any Cache-Control Header

Paste the raw Cache-Control value from an HTTP response and this analyzer breaks it into directives, computes the freshness lifetime for browsers and shared (CDN/proxy) caches, and gives you a plain-English verdict on whether the response is actually cacheable — plus warnings for conflicting or redundant directives.

Verdict

Directives found

DirectiveValueMeaning

Analysis & warnings

How the analyzer works

The tool tokenizes the header on commas, then splits each token on the first = into a directive name and an optional argument. Names are lower-cased (they are case-insensitive per RFC 9111), and arguments that should be integers — max-age, s-maxage, stale-while-revalidate, stale-if-error, min-fresh, max-stale — are parsed as delta-seconds. Values are then rendered as human-readable durations (for example 86400 becomes 1 day).

Freshness lifetime is computed with the RFC 9111 precedence rules. A shared cache uses s-maxage if present, otherwise max-age, otherwise there is no explicit lifetime. A private (browser) cache ignores s-maxage entirely and uses max-age. Any freshness lifetime is overridden to zero when no-cache (revalidate every use), max-age=0, or must-revalidate with an expired copy applies, and cacheability is denied outright by no-store. The formula is: fresh_for = has(s-maxage) && shared ? s-maxage : (has(max-age) ? max-age : none), then fresh_for = no-cache ? 0 : fresh_for.

The verdict combines these: no-store means not stored at all; private blocks shared caches; public or a positive max-age makes a response storable even when it would not otherwise be. Warnings flag mutually exclusive combinations (no-store beside a positive max-age), redundant pairs (no-cache with max-age=0), a private response carrying s-maxage that shared caches will discard, missing units, and unrecognized directive names so you can catch typos like max_age before they ship.

Related Tools