Choose cache directives to compose a header, or paste an existing value for analysis. This checks header text, not a live cache.
Runs locally in your browserThe upper panel composes a response policy: choose a visibility, add a freshness lifetime in seconds, tick the flags you need and press Build header. The header the page would send appears in the Response header box with a three-line summary — how many directives, how fresh the response is, and which caches may keep it — followed by every conflict the combination contains. The lower panel works the other way round: paste a value copied from a response, a CDN setting or a log, press Inspect header, and read the same summary for that text. Both panels run in this browser and the page keeps working offline.
Cache-Control is the HTTP response field that tells caches how long a response may be reused and what they must check first: max-age and s-maxage set the lifetime for browsers and shared caches, no-store forbids storing, no-cache allows storing but demands validation, and immutable, stale-while-revalidate and stale-if-error refine that. This tool reads the header text against RFC 9111 and reports what a cache would make of it. It never contacts a URL, so it cannot tell you what your server, your CDN or a browser cache actually does at runtime.
public and private contradict each other: public marks the response as storable by shared caches, and private forbids exactly those caches from keeping it, so one of the two has to go. no-store is the strongest directive — nothing may be stored — which makes max-age, s-maxage and the stale windows pointless in the same header; the report says so instead of showing a lifetime that will never be applied. s-maxage is read by shared caches only, and private excludes them, so s-maxage next to private has no effect.
immutable promises that the resource will not change while it is fresh (RFC 8246); without max-age or s-maxage no freshness window is stated for the promise to cover. must-understand belongs next to no-store, and a cache that understands the status code's caching requirements ignores the no-store part (RFC 9111 section 5.2.2.3). A missing lifetime is reported as well: without max-age, s-maxage or no-cache, a cache may fall back to a heuristic — commonly a tenth of the time since Last-Modified — and reuse the response without asking the origin.
max-age, s-maxage, stale-while-revalidate and stale-if-error take delta-seconds, which RFC 9111 defines as one or more digits (section 1.2.2): 0 is a valid value and means stale immediately, and a decimal point is not part of the grammar. A quoted value such as max-age="5" is reported because a sender must use the token form (section 5.2.2.1). A value above 2147483647 seconds is flagged as well: a cache that cannot represent the number must read it as 2147483648 seconds, over 68 years, which behaves like never stale.
The other argument form in this field is the quoted field-name list of no-cache and private, as in no-cache="Set-Cookie". Commas inside those quotation marks belong to the list, which is why the parser splits the field on commas outside quotes and counts such a value as one directive. Directives a cache does not recognize are ignored by that cache (section 5.2.3), and that is exactly why a misspelling such as maz-age=60 is worth reporting: the response would still be served, and the rule would simply not exist.
The page never sends a request; it reads header text only. Whether a CDN, a reverse proxy or a browser honours the field depends on that system's configuration and on the status code of the response, and a cache may store a response that carries no directives at all if it considers it heuristically cacheable. Check the policy on the live response — curl -I, the cache headers your CDN reports, or the browser network panel — before trusting it.
Two neighbours of this field are deliberately out of scope: Expires gives an absolute date instead of a lifetime, and Pragma is an HTTP/1.0 request field that RFC 9111 deprecates (section 5.4). A line that starts with another field name is refused for that reason rather than relabelled as Cache-Control. And because the check is textual, a header that reads perfectly can still be wrong for the content behind it: no-store on a static asset, or a one-year max-age on a page that changes hourly, are decisions no header checker can make for you.