← Back to Blog

Cache-Control and Stale Content: Why Users Still See the Old Page

HTTP · May 28, 2026 · 5 min read

You deployed a fix but users report seeing the old version. Cache-Control headers, CDN caching, and browser back-forward cache are the usual suspects.

Technical cover image for Cache-Control and Stale Content: Why Users Still See the Old Page

You Deployed a Fix. Users Still See the Old Version.

You push a critical fix, clear the application cache, and confirm the change on your machine. Five minutes later, a user sends a screenshot of the old broken page. The problem is not your deployment pipeline — it is caching at layers you might not have considered.

Start with OpsCheck HTTP Headers to inspect the Cache-Control header your server sends. Then use curl to simulate what different clients see.

The Cache Layers Between You and Your Users

# Check what headers your origin sends
curl -s -D - -o /dev/null https://example.com/ | grep -i cache

# Simulate a fresh request (bypass client cache)
curl -H "Cache-Control: no-cache" -H "Pragma: no-cache" -s -D - -o /dev/null https://example.com/

# Check what a CDN edge returns (look for X-Cache, CF-Cache-Status)
curl -s -D - -o /dev/null https://example.com/ | grep -iE "x-cache|cf-cache|age|etag"

Interpreting Cache-Control Headers

# Common Cache-Control values and what they mean:

# public, max-age=3600 — cache for 1 hour, including CDNs
# private, max-age=0 — browser can cache, CDNs cannot
# no-cache — must revalidate before serving, but CAN store
# no-store — must not store at all (most aggressive)
# s-maxage=600 — CDN caches for 10 min regardless of max-age

# Check the Age header — shows how long the CDN has held this copy
curl -s -D - -o /dev/null https://example.com/ | grep "^Age:"

Real-World Scenario

An ops team deployed an urgent CSS fix at 14:00. The server sent Cache-Control: public, max-age=86400, and the CDN had already cached the old CSS with a 24-hour TTL. Users kept getting the broken stylesheet. The fix: changing the CSS file URL to include a content hash (style.a1b2c3d.css) so the CDN treated it as a new resource. The old URL eventually expired. Using OpsCheck Timestamp Converter, they verified the Age header matched the old deployment time precisely. The OpsCheck Hash Generator confirmed the new CSS file had a different SHA-256 from the cached version.

# Verify content integrity
curl -s https://example.com/style.css | sha256sum
# Compare with the known-good file hash from your build

Checklist for Stale Content Issues

  • Check Cache-Control: is it public with a high max-age? CDNs will hold it
  • Check the Age header — if > 0, a cache layer is serving this
  • Look for X-Cache: HIT or CF-Cache-Status: HIT — confirms CDN caching
  • If you need instant invalidation, version your assets (app.v2.css instead of app.css)
  • For HTML pages, consider Cache-Control: no-cache to force revalidation
  • Browser back-forward cache (bfcache) can also serve stale pages — test with a fresh tab