A dynamic article page has high origin TTFB in distant regions. Enabling cache-everything makes it fast, but an authenticated preview and a language variant can be stored under the same key as the public page.
Use the sequence below as a diagnostic method, not as a promise that one setting fits every host; verify its example paths, privileges, and backup assumptions while working to design cache keys, browser and edge TTLs, validators, stale windows, purge paths, and privacy exclusions for consistently low page latency.
Likely failure paths
- The cache key omits a representation dimension such as host, path, language, or a validated device variant.
- Responses with cookies, authorization, drafts, carts, or personal data are accidentally shared.
- A long TTL reduces latency but leaves no tested purge or background-revalidation path after publication.
The branches are ordered to protect the strongest evidence around this possibility: the cache key omits a representation dimension such as host, path, language, or a validated device variant. The observed scope and logs—not a familiar-looking error screen—decide which one applies.
Page latency is a chain: redirects and connection setup precede server response, critical resources precede rendering, and main-thread work precedes interaction; optimize the measured segment instead of adding every available hint or cache directive; in this guide, the practical goal is to design cache keys, browser and edge TTLs, validators, stale windows, purge paths, and privacy exclusions for consistently low page latency.
A controlled investigation
- Classify routes as public shared, private, pass-through, or conditionally cacheable before writing a CDN rule.
- Inspect Cache-Control, CDN-specific cache headers, Age, Vary, ETag, Set-Cookie, and the provider cache-status header.
- Request two users, languages, query strings, and hostnames to prove the cache key separates every intended representation.
- Measure hit ratio, shield or origin requests, revalidation duration, stale responses, and purge propagation.
The sequence moves from observation toward intervention. Preserve the result of the final check—measure hit ratio, shield or origin requests, revalidation duration, stale responses, and purge propagation—because it provides a useful comparison after the repair.
A bounded staging experiment
The opening hypothesis is the cache key omits a representation dimension such as host, path, language, or a validated device variant. Test it with the least invasive observation available: classify routes as public shared, private, pass-through, or conditionally cacheable before writing a CDN rule. Do not change configuration until the observation has been saved with a timestamp.
When that evidence is consistent with the hypothesis, stage this repair: cache only public GET/HEAD responses and explicitly bypass authenticated, preview, checkout, account, and error routes. Otherwise, preserve the current state and advance to the next branch. This keeps rollback simple and prevents a second change from masking the first.
Make the smallest durable change
- Cache only public GET/HEAD responses and explicitly bypass authenticated, preview, checkout, account, and error routes.
- Give browsers a conservative policy and the edge a separate shared TTL with a bounded stale-while-revalidate window.
- Use versioned assets and a narrow purge by URL or tag for content that must change immediately.
Before applying “Cache only public GET/HEAD responses and explicitly bypass authenticated, preview, checkout, account, and error routes,” name its rollback point and the evidence that will count as success. Afterward, repeat the original request and specifically check whether you can confirm HIT, MISS, revalidation, and expired behavior with saved response headers from several regions; a changed symptom at that point is new evidence, not permission to make several more changes at once.
Separate browser freshness from shared edge freshness
This response policy keeps browser caching short while allowing a shared cache to reuse a public article and refresh it in the background.
location /articles/ {
proxy_pass http://public_origin;
proxy_hide_header Set-Cookie;
add_header Cache-Control "public, max-age=60, s-maxage=600, stale-while-revalidate=30" always;
}
location ~ ^/(account|checkout|preview)/ {
proxy_pass http://private_origin;
add_header Cache-Control "private, no-store" always;
}
Interpretation and safety: Do not copy this until authentication, error caching, query handling, Vary, and CDN behavior are verified. Hiding Set-Cookie is safe only for a route proven to be public.
Close the incident with evidence
- Confirm HIT, MISS, revalidation, and expired behavior with saved response headers from several regions.
- Change one article and prove its purge does not evict unrelated content or leave the old variant accessible.
- Test origin failure and decide which pages may be served stale versus returning an honest error.
One successful refresh is not closure. Keep the incident open until you can also change one article and prove its purge does not evict unrelated content or leave the old variant accessible, adjacent paths have not regressed, temporary diagnostics are gone, and another operator can explain what changed.
Prepare a useful escalation if the boundary is outside your control
Preserve field percentiles by page type and geography, a repeatable lab trace, cache status, response headers, resource waterfall, deployment ID, and the measured LCP element; compare like-for-like cache and network states; include the result of this first observation: classify routes as public shared, private, pass-through, or conditionally cacheable before writing a CDN rule.
State what was tested, including the result of “Classify routes as public shared, private, pass-through, or conditionally cacheable before writing a CDN rule,” and what changed between attempts; evidence tied to that observation is safer and more actionable than granting broad access or sending an unnecessary full database export.
Do not trade visibility for a green screen
- Do not cache responses merely because they return 200.
- Do not include unbounded tracking parameters or cookies in the cache key and destroy hit ratio.
Change record
Primary references
- Cloudflare cache configuration — official reference consulted for this guide.
- MDN HTTP caching — official reference consulted for this guide.
Editorial note: The scenario above illustrates how to approach “Cache only public GET/HEAD responses and explicitly bypass authenticated, preview, checkout, account, and error routes”; it is a documented example, not a claim about a reader’s server, so verify the cited documentation, take the appropriate backup, and follow the real environment’s access and change-control rules.