Cache & CDN: Am I Seeing an Old Cached Version?
Using curl and DevTools to tell whether a response was served from cache and by what.
Tools required: curl
Overview
"I updated the site but I still see the old version" is one of the most common support tickets, and it's almost always a caching question, not a deployment failure. This guide shows how to tell the difference.
Step-by-Step Manual Check
Check the Cache-Control and CDN status headers
These headers tell you both how long a browser/CDN is allowed to cache the response, and whether this particular response was actually served from cache.
curl -I https://example.com | grep -i "cache-control\|cf-cache-status\|age\|etag"cf-cache-status only appears on sites behind Cloudflare - other CDNs use their own header (e.g. x-cache on CloudFront/Akamai).
Healthy result
cache-control: public, max-age=3600 cf-cache-status: HIT age: 120 etag: "abc123"
Problem result
cache-control: no-store (no cf-cache-status/x-cache header at all, or cf-cache-status: MISS on every request)
What it means
cf-cache-status: HIT with a non-zero age means you're looking at a cached copy - if content just changed, the cache hasn't caught up yet. cf-cache-status: MISS or DYNAMIC on every request means nothing is being cached at all - a different problem (performance, not staleness) but confirms the CDN isn't the reason you're seeing an old version.
If unresolved, escalate to: Level 2 — Intermediate
Force a cache bypass and compare
Deliberately requesting a fresh copy proves whether the origin server has actually updated, isolating a cache problem from a real deployment problem.
curl -H "Cache-Control: no-cache" -I https://example.comHealthy result
Response content/ETag differs from the cached version, confirming the origin does have the new content.
Problem result
Response is identical even with the cache-bypass header sent.
What it means
If bypassing cache still shows the old content, the deployment itself didn't actually update the origin server - that's not a caching issue at all, and points back to the deployment/publish process instead.
If unresolved, escalate to: Level 2 — Intermediate
Confirm in the browser with a hard refresh
Rules out the browser's own local disk/memory cache as a separate layer from the CDN.
Hard refresh: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac). Then check Network tab - the Size column shows "(from disk cache)" or "(from memory cache)" versus an actual transferred size.Healthy result
After hard refresh, Size column shows a real byte count (not "from cache"), and the new content is visible.
Problem result
Even after a hard refresh, old content persists.
What it means
If a hard refresh (which bypasses the browser's local cache) still shows old content, the staleness is happening upstream - at the CDN or origin - not in the visitor's browser, pointing back to Step 1/2.
If unresolved, escalate to: Level 1 — Basic
Interpreting the Results
Work from the visitor inward: browser cache (Step 3) is the fastest to rule out and the most common false alarm, CDN cache (Step 1) is next most likely, and "the deployment didn't actually publish" (Step 2) is the least common but most serious cause since no amount of cache-clearing will fix it.
Common Causes
| Symptom | Likely Cause | Fix |
|---|---|---|
| New content shows in incognito/private browsing but not normal browser | Local browser cache holding the old version | Hard refresh, or clear the site's cached data in browser settings. |
| cf-cache-status: HIT with a large age value after a recent update | CDN edge cache hasn't expired yet | Purge the CDN cache for the changed URL, or wait out the configured max-age. |
| Fresh content never appears even with cache bypassed | The deployment didn't actually reach the origin server | Check the deployment/build pipeline - this is not a caching issue. |
Automated by
Diagnostic Suite - Site Latency Diagnostic (Option 2)
Automatically reads Cache-Control and CDN cache-status headers as part of its full report.