What is the Cache-Control header?
The Cache-Control header specifies instructions for caching in both client browsers and intermediary proxies (like CDNs).
API Usage & Best Practices
- Sensitive or per-user data:
no-storeon its own:no-storeforbids every cache, private and shared, from storing the response. Addingno-cache,must-revalidateormax-age=0to it changes nothing for a cache that follows RFC 9111, so sendCache-Control: no-storeand stop there. - Per-user data the browser may keep:
private:privatelets the client’s own cache store the response but keeps it out of shared caches such as CDNs and proxies. Pair it withmax-agefor a freshness window, or withno-cacheto make the client revalidate with itsETagon every use. - Shared data:
max-agepluss-maxage: For responses that are the same for every caller (country lists, public configuration), usepublic, max-age=60, s-maxage=86400.s-maxageoverridesmax-agefor shared caches only, so the CDN can hold the response longer than browsers do. A shared cache will not reuse a response to a request with anAuthorizationheader unless it carriespublic,s-maxageormust-revalidate. - Mutations need nothing extra: RFC 9110 makes responses to
PUTandDELETEnon-cacheable, and aPOSTresponse is cacheable only with explicit freshness information and a matchingContent-Location. You do not need to decorate write responses to keep them out of caches. - Target the CDN separately: To give your CDN different instructions from browsers without touching
Cache-Control, useCDN-Cache-Control. To see what a cache actually did with a response, readCache-Status.
Examples
A per-user response no cache should store:
HTTP/1.1 200 OKCache-Control: no-storeA shared response, cached briefly by browsers and for a day by the CDN:
HTTP/1.1 200 OKCache-Control: public, max-age=60, s-maxage=86400