What is the CDN-Cache-Control header?
The CDN-Cache-Control response header, defined in RFC 9213, carries the same directives as Cache-Control but applies only to CDN caches: caches in a distributed network acting on behalf of the origin. It lets an origin tell the edge one thing and browsers and other caches another, without the overloading that s-maxage does across every shared cache.
RFC 9213 calls this a targeted cache-control field. A cache that supports one keeps an ordered target list of field names. For each response, it uses the first field on that list with a valid, non-empty value, and when it does, it ignores Cache-Control and Expires entirely for that response. If none is valid, normal HTTP caching applies. Caches not targeted by the field must ignore it and pass it through.
Unlike Cache-Control, it is a Structured Field Dictionary. Directives such as max-age=600 and no-store look the same, but a value that fails to parse makes the cache ignore the whole field, as though it were absent.
API Usage & Best Practices
- Cache at the edge, not in the browser. The commonest use: let the CDN hold a response for minutes while clients revalidate on every request.
CDN-Cache-Control: max-age=600withCache-Control: no-cachedoes exactly that. - Keep a sensible
Cache-Controlalongside it. Caches that do not understandCDN-Cache-Controlfall back toCache-Control. Never send only the targeted field and assume nothing else will cache the response. - Purge when you lengthen edge TTLs. A long CDN freshness lifetime means updates do not reach clients until the CDN entry expires or is purged. See CDN and edge caching and cache invalidation.
- Watch the
Ageit produces. A CDN holding a response longer thanCache-Control: max-ageallows will forward it with anAgethat already exceedsmax-age, so downstream caches treat it as stale immediately. RFC 9213 lets implementations mitigate this by removingAgeor updatingDate, but does not require it. Check what your CDN does. - To keep responses out of every cache except the CDN, send
Cache-Control: no-storewith a non-emptyCDN-Cache-Control. RFC 9213’s own example usesCDN-Cache-Control: none, which is not a registered directive but stops the field being empty, so the CDN obeys it instead ofno-storeand falls back on its own defaults. - Never use it for personalized responses. Responses that depend on
Authorizationor a cookie must not be cached at the edge unless the cache key includes the identity.privateinCDN-Cache-Controlis honored, but the safer default is not to send an edge-cacheable directive at all on authenticated endpoints. - Know your CDN’s own field. RFC 9213 expects CDNs to define their own more specific fields that sit ahead of
CDN-Cache-Controlon the target list. Cloudflare, for example, supports bothCDN-Cache-Control, which it obeys and passes downstream to other CDNs, andCloudflare-CDN-Cache-Control, which only Cloudflare obeys and which it does not forward. When both are present, Cloudflare uses the more specific one. Check your provider’s documentation rather than assuming.
Examples
Edge caching for ten minutes, with browsers revalidating every time:
HTTP/1.1 200 OKContent-Type: application/jsonETag: "v42"Cache-Control: no-cacheCDN-Cache-Control: max-age=600A CDN-specific lifetime with a general fallback for other shared caches, taken from RFC 9213:
HTTP/1.1 200 OKContent-Type: application/jsonCache-Control: max-age=60, s-maxage=120CDN-Cache-Control: max-age=600Stored by CDN caches for ten minutes, and by no other cache:
HTTP/1.1 200 OKContent-Type: application/jsonCache-Control: no-storeCDN-Cache-Control: max-age=600