Pure-reference catalog of cache-coherence patterns across the request path. Defines the five-tier cache stack (browser → CDN → reverse-proxy → application → data store), the per-tier cache-writing patterns (cache-aside, write-through, write-back, write-around, refresh-ahead), and the canonical invalidation strategies (TTL-only, event-driven purge, surrogate keys, version-tagged URLs, soft purge), plus an anti-pattern table and a worked multi-tenant coherence-test example. Deep detail lives in references/: RFC 9111 Cache-Control / Vary / ETag directive tables, the cross-tier test surface, cache-stampede (thundering-herd) mitigations incl. the XFetch formula, and RFC 5861 stale-while-revalidate / stale-if-error semantics. Use for pattern selection, Cache-Control header design, coherence audits, stampede-refresh strategy, and SWR/SIE window design; use a cache-key-collision check when the question is whether two concrete requests collide on a key scheme.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
A cache stampede ("dog-piling") occurs when a cached value expires under high load - many requesters simultaneously detect the miss, all recompute, all write back. Per en.wikipedia.org/wiki/Cache_stampede, the pathological state is "congestion collapse, preventing the resource from being recached and maintaining zero cache hit rates."
| Signal | Interpretation |
|---|---|
| DB / upstream latency spikes at cache-key TTL boundaries | Stampede on key expiry |
| Cache hit rate drops near zero, recovers slowly | Congestion collapse |
| Load spikes synchronised with cron / scheduled jobs | Multiple processes invalidating + recomputing |
| Recompute-cost-vs-traffic ratio > 0.1 | Hot key - stampede risk |
Per the Wikipedia article; full code, drawbacks, and the XFetch variable table are in stampede-mitigations.md.
if (!value || (time() - delta * beta * log(rand(0,1))) >= expiry)
recompute_and_cache(key)
else
return valuePer Wikipedia, "setting beta=1 works well in practice." Measure delta
(recompute cost) during refresh and store it beside value and expiry.
Choose by key knowability: XFetch for unknown / user-specific keys, external recompute for known-hot keys, locking as a backstop. The strongest setups layer them:
| Layer | Strategy |
|---|---|
| Cache backend | TTL + stale-while-revalidate (stale-while-revalidate.md) |
| App logic | XFetch on read for hot keys |
| Operations | External recompute for known-hot keys |
| Safety net | Distributed lock (Redis SET NX EX) |
A homepage "top-10 products" aggregate under one key with ttl=300
expires at the traffic peak; ~1,200 concurrent misses hit the database and
the hit rate collapses for ~40s. The key is known and hot, so external
recomputation fits: a cron refreshes it every 240s, with XFetch on read as
a backstop for a missed cron run. The load test below then asserts the
upstream sees <=5 recomputes, down from ~1,000.
| Behaviour | Test |
|---|---|
| Lock holds under contention | N concurrent gets on a missing key → 1 recompute, N-1 wait/stale |
| XFetch probability rises near expiry | Statistical: fraction refreshing early within target band |
| External recompute fires before TTL | Write source → wait → assert cache reflects new value |
| Stampede absent under load | N=1000 concurrent on cold key → upstream sees 1-5 recomputes |
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| No mitigation at all | Stampede inevitable under traffic | Pick at least one family |
| Lock without TTL | Lock-holder crash → deadlock | TTL on locks |
XFetch with very high beta (10+) | Everyone refreshes constantly | beta=1; tune via load test |
| External recompute without monitoring | Failed cron → stampedes return silently | Alarm on cache-miss-rate spike |
Hot key with must-revalidate | Forced revalidation = forced stampede at TTL | SWR or grace mode |
| Mitigation tested only at low load | Passes at 10 RPS, fails at 1000 | Production-equivalent concurrency |
delta to p95, not mean.