← Back to Caching Open Cache Rules in Dashboard ↗

~/cache-rules

// Make edge caching tangible — inspect HIT/MISS, cache keys, bypass logic

Cache Status Explorer

Fire requests against four endpoints. Watch x-cache-status flip MISS → HIT on the second call. Re-run to replay.

📰 Real-world: Online newspaper

Your homepage HTML sees 100k requests during breaking news. Set Edge TTL to 30s — readers still see fresh headlines, but your origin handles ~2 requests/minute for that page instead of 100k. Meanwhile /logo.png changes once a decade (cache it for a year) and /api/user/balance is per-user (don't cache at all). Same site, three TTL strategies per URL pattern — exactly what the four endpoints below simulate.

Cacheable resources

These have Cache-Control: public, max-age=N and match Cache Rules. Expect MISS first, HIT after.

TTL 60s · click to start
TTL 30s · click to start
TTL 10s · click to start

Non-cacheable

No Cache-Control header. Expect DYNAMIC every time — the worker runs on every request.

no cache · always DYNAMIC
// No requests yet. Click a button above.

Cache Key Playground

The cache key decides when two requests share a cached response. Change variant and v and fire against each endpoint — same X-Origin-Id = same cached response.

🛍️ Real-world: Marketing campaign fragmentation

You run ads that send traffic to /shoes?utm_source=twitter&utm_campaign=spring. Every unique UTM combo is a different URL, so by default Cloudflare treats each one as a separate cache entry. A 50-variant campaign creates 50 cached copies of the same page — your cache hit rate crashes from 95% to 5% the day marketing ships. Fix: tell the cache key to ignore utm_* query strings. One cache entry, hit rate restored. The three endpoints below show the three most common key strategies: include everything, ignore everything, or include specific params only.

Request params

Fire against

Each endpoint has a different Cache Rule cache-key strategy.

// Tip: fire default with v=1, then v=2 → two MISSes. Fire ignore-all with v=1, v=2 → MISS then HIT.

Bypass on Cookie

Same URL, two fates. Anonymous requests HIT the edge cache. Requests carrying logged_in=true BYPASS cache entirely so you never serve a user's private HTML to a stranger.

🛒 Real-world: E-commerce cart indicator

Your product page shows "🛒 0 items" in the header for everyone — until someone clicks "Add to cart", and then it needs to say "🛒 1 item". If the page is cached, every visitor at that POP keeps seeing "0 items" even after they added something. Solution: the app sets a cart_count cookie on add-to-cart. The Cache Rule says: if the cookie exists, bypass cache. The 99% of traffic browsing anonymously gets the blazing-fast cached page; the 1% actively shopping gets a fresh render with the right count. Login/logout below simulates exactly this.

Session state

Simulate login/logout. The cookie is set by /session/login.

Anonymous

Fire requests

Hit /origin/bypass a few times — watch status change when you toggle the cookie.

TTL 60s (anonymous) · BYPASS when logged in
// Expected flow: anonymous MISS → HIT → HIT. Login → BYPASS → BYPASS. Logout → HIT.

Cache TTL by Status Code

One Cache Rule, different TTLs per response status. 200 caches for 5 min, 301 for 1 min, 404 for 30 s, 5xx bypasses cache so bugs don't get pinned to the edge.

⚠️ Real-world: Public SaaS API during a database hiccup

It's 3am. Your database has a transient outage and your API starts returning 500s. Without status-code TTLs, Cloudflare caches those 500s for 5 minutes across every POP globally — by the time you fix the database, users are still getting stale cached errors everywhere, even though your origin has recovered. With status-code TTLs: 5xx is never cached. The database recovers, the next request produces a fresh 200, users are happy. Meanwhile 200s still cache aggressively and 404s cache briefly so you don't spam origin with lookups for deleted endpoints. The four buttons below fire each scenario.

Fire different statuses

Each button hits /origin/status/{code}. Origin returns that status every time — watch how the edge TTL differs.

TTL 300s · click to start
TTL 60s · click to start
TTL 30s · click to start
no cache · always BYPASS

What to observe

Fire any button twice — the cacheable ones (200, 301, 404) MISS then HIT. 500 always shows DYNAMIC or BYPASS because 5xx isn't cache-eligible.

TTL table:
200 → 300 s · 301 → 60 s · 404 → 30 s · 5xx → no cache

// Status-code-based TTLs are configured in a single Cache Rule via edge_ttl.status_code_ttl[].