[Cache] Document CDN-Cache-Control as a BYPASS cause - #32569
Conversation
- Add a BYPASS bullet documenting Cloudflare-CDN-Cache-Control and CDN-Cache-Control, and their precedence over Cache-Control. An origin returning cacheable Cache-Control alongside a non-cacheable CDN-Cache-Control directive produces BYPASS, and readers otherwise have no signal that these two headers even exist as BYPASS causes. - Rewrite the Age callout and HIT confirmation to describe the Tiered Cache lower-tier fill in plain language, without referring to the internal CacheTieredFill=true field. That field is only visible in the http_requests Logpush dataset, not in HTTP responses, so it is not something readers can inspect.
Review
Code ReviewThis code review is in beta and may not always be helpful — use your judgment. No code review issues found. Conventions❌ This review could not complete this run; results may be incomplete. It will retry on the next push. Style Guide ReviewNo style-guide issues found. CommandsOnly codeowners can run commands. Post a comment with the command to trigger it.
|
|
This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:
|
Address SG-619a15c3d17a from the docs bot review.
| @@ -15,7 +15,7 @@ The `CF-Cache-Status` header output indicates whether a resource is cached or no | |||
| :::note[`Age` response header] | |||
| The `Age` response header is a header returned from cache that specifies the time in seconds that an asset has been in Cloudflare's cache. This value resets if the asset is revalidated, purged, or evicted and then re-cached. | |||
There was a problem hiding this comment.
As we're making this note more clear, I suggest updating this paragraph too, e.g. Cloudflare's cache is vague.
| The `Age` response header is a header returned from cache that specifies the time in seconds that an asset has been in Cloudflare's cache. This value resets if the asset is revalidated, purged, or evicted and then re-cached. | |
| The `Age` response header is returned when Cloudflare serves a response from a local cache object on the data center handling the request. It is the number of seconds since that object was admitted or last revalidated at that cache. It resets if the asset is revalidated, purged, or evicted and then re-cached. |
There was a problem hiding this comment.
[AI] Thanks @foreseaz — applied in 7ebf4751. Per-data-center scope is more accurate, and it also lines up with the second paragraph of the callout (which describes Tiered Cache behavior between lower and upper tiers).
Clarify that Age is per-data-center scope: the seconds since the serving data center's local cache admitted or last revalidated the object, rather than the vaguer 'time in Cloudflare's cache'. Applies @foreseaz's suggestion.
| The `Age` response header is a header returned from cache that specifies the time in seconds that an asset has been in Cloudflare's cache. This value resets if the asset is revalidated, purged, or evicted and then re-cached. | ||
|
|
||
| The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates the lower tier HIT from tiered cache `CacheTieredFill=true` or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache). | ||
| The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates a lower-tier data center's cache from an upper tier via [Tiered Cache](/cache/how-to/tiered-cache/), or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache). |
There was a problem hiding this comment.
LGTM on clarifying the tiered-cache case.
Optional follow-up: this note still underspecifies when Age appears. We only set it for pure local cache serves (HIT / STALE / UPDATING) — not REVALIDATED, EXPIRED, or BYPASS.
Suggest update:
| The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates a lower-tier data center's cache from an upper tier via [Tiered Cache](/cache/how-to/tiered-cache/), or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache). | |
| `Age` is typically present for `HIT`, `STALE`, and `UPDATING`. | |
| It is not present for: | |
| - `MISS`, `EXPIRED`, `REVALIDATED`, `BYPASS`, `DYNAMIC`, and `NONE`/`UNKNOWN` | |
| - the first request that populates a lower-tier data center's cache from an upper tier via [Tiered Cache](/cache/how-to/tiered-cache/) (even if `CF-Cache-Status` is `HIT`) | |
| - responses that never hit cache (for example, a Worker that bypassed the cache) | |
| After that lower-tier data center is populated, later local hits include `Age`. |
There was a problem hiding this comment.
this suggestion needs another look from @zaidoon1 or other folks.
| Common reasons the origin response is treated as not cacheable include: | ||
|
|
||
| * The response exceeds the [maximum cacheable file size](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan. | ||
| * The origin returned a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header with a non-cacheable directive. Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. For example, an origin returning both `Cache-Control: public, max-age=3600` and `CDN-Cache-Control: no-store` produces `BYPASS`. Inspect every response header, not just `Cache-Control`. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules. |
There was a problem hiding this comment.
good call, maybe we want to mention Surrogate-Control too.
Cloudflare-CDN-CC > CDN-CC > Surrogate-Control > Cache-Control
cc @zaidoon1
|
Both changes LGTM. Left some nits to make the existing change more clear, thanks for the effort @ngayerie |
Two small follow-ups to #32423.
What
cache-responses.mdxandinvestigating-uncached-responses.mdxdocumentingCloudflare-CDN-Cache-ControlandCDN-Cache-Control, with the precedence chainCloudflare-CDN-Cache-Control>CDN-Cache-Control>Cache-Control. Uses a concrete example so the reader sees that a cacheableCache-Controlalongside a non-cacheableCDN-Cache-Controlstill producesBYPASS.Agecallout incache-responses.mdxand the corresponding HIT-verification bullet in the troubleshooting page. Both currently mentionCacheTieredFill=true, which is anhttp_requestsLogpush field, not an HTTP header — readers cannot observe it on a response.Why
Neither BYPASS list mentioned
Cloudflare-CDN-Cache-ControlorCDN-Cache-Control. When bothCache-ControlandCDN-Cache-Controlare set,CDN-Cache-Controlwins per CDN-Cache-Control, so a reader debugging aBYPASSwhile only looking atCache-Controlhas no signal from these pages that another header is in play.@zaidoon1 for review.