A cache stampede happens when a popular cached item expires, and many concurrent requests miss the cache at the same moment, forcing every one of them to hit the backend to rebuild the same value. That sudden flood of duplicate work can spike database load, slow response times, and trigger outages during your heaviest traffic. This guide breaks down what a cache stampede is, why it happens, and the proven techniques that stop it, from cache locking and stale-while-revalidate to randomized TTLs and edge caching. The failure stays quiet until the exact moment you can least afford it.

Key Takeaways

  • A cache stampede (also called the dogpile effect or thundering herd) occurs when many requests rebuild the same expired cache key at the same time.
  • The root trigger is usually synchronized expiration: many keys, or many requests on one key, hitting the instant a TTL reaches zero.
  • Under high concurrency, one expired key can turn thousands of fast cache hits into thousands of expensive database queries in milliseconds.
  • Cache locking, request coalescing, stale-while-revalidate, randomized TTL, and cache warming are the five core prevention techniques.
  • Redis caches are common stampede targets, and single-flight locking or probabilistic early expiration solve most cases.
  • A CDN layer absorbs stampedes by coalescing edge misses into one origin fetch, shielding the backend from concurrent load.

How a Cache Stampede Overloads Your Backend

A cache stampede overloads your backend because the moment a cached value expires, every request that would normally be served from cache instead misses and races to regenerate the same data from the origin.

Under normal conditions, a cache sits between users and your database and answers most requests in microseconds. The backend stays idle for the hot keys because the cache carries the load. That balance holds only while the cached value exists.

When the key expires, the safety net disappears for everyone at once. Ten thousand requests per second that were hitting cache now become ten thousand requests hitting your database, each trying to recompute an identical result. The backend was never sized for that surge, so latency climbs, connections saturate, and users meet the kind of slow website performance that pushes them to leave.

  1. The cached key reaches its TTL and is evicted.
  2. Concurrent requests all check the cache and get a miss.
  3. Each request independently queries the origin to rebuild the value.
  4. The backend absorbs a burst of identical, expensive work.
  5. Regeneration lags, the cache stays cold, and the pile grows.

A media site we reviewed cached its homepage feed for exactly 60 seconds. Every minute, on the tick, roughly 8,000 requests missed together and hammered the same three database joins. Their p99 latency jumped from 40 ms to 2.3 seconds once a minute, like clockwork.

Dogpile Effect vs Thundering Herd

The dogpile effect and the thundering herd problem describe the same event as a cache stampede: many processes waking at once to compete for a single resource that just became unavailable.

The thundering herd term comes from operating systems, where many processes blocked on one event all wake when it fires even though only one can proceed. The dogpile effect is the caching community’s name for the same pattern applied to an expired key.

You might be thinking these are separate bugs with separate fixes. They are not. A solution that serializes regeneration, like cache locking, resolves all three at once because it attacks the shared root, which is uncoordinated concurrent rebuilds.

Pro Tip
When you search vendor documentation, query all three terms. Redis docs often use thundering herd, application caching libraries commonly use dogpile, and CDN documentation typically refers to cache stampede. Combining these terms helps you find more complete technical solutions.

Knowing the vocabulary matters less than knowing what pulls the trigger.

What Causes a Cache Stampede?

A cache stampede is caused by the combination of synchronized cache expiration and high request concurrency on a value that is expensive to regenerate.

Three conditions have to line up. First, a key many clients depend on. Second, an expiration event that fires while those clients are actively requesting it, which is common during traffic spikes. Third, a rebuild cost high enough that the regeneration window stays open long enough for requests to stack.

The most common trigger is a fixed TTL applied uniformly. If you cache 500 product pages for exactly one hour after a deploy, all 500 expire in the same second an hour later, and every one stampedes together.

  • Uniform, fixed TTLs that cause many keys to expire simultaneously.
  • A single hot key under very high concurrent read traffic.
  • Expensive origin work (heavy joins, external API calls, large renders) that widens the rebuild window.
  • Cold starts after a deploy, cache flush, or node restart that empty the cache all at once.
  • Aggressive invalidation that clears popular keys during peak traffic.

What most people miss: lowering your TTL to keep data fresher makes stampedes more frequent, not less. Shorter TTLs mean more expiration events per hour, and each one is another chance for the herd to charge. Freshness and stampede risk pull in opposite directions.

An e-commerce team dropped their category-page TTL from 10 minutes to 60 seconds to show live stock counts. Stampede incidents rose tenfold in a week because they had created ten times as many expiration moments.

Once you know the triggers, the fixes follow a clear pattern.

How to Solve a Cache Stampede: 4 Prevention Techniques

You solve a cache stampede by making sure only one request rebuilds an expired key while the rest wait, serve stale data, or avoid expiring together in the first place.

Every effective fix pulls one of two levers: reduce how many requests rebuild at once, or reduce how often keys expire together. The four techniques below cover the vast majority of production cases and combine well.

How to Solve a Cache Stampede

Technique How it works Best for Trade-off
Cache Locking The first request locks the cache key and rebuilds the data; others wait or receive stale content. Single hot keys May add a short delay if cache rebuilding is slow
Stale-While-Revalidate Serves the expired cache value immediately while refreshing it in the background. Read-heavy content Users may receive slightly outdated data
Randomized TTL Adds timing variation so multiple cache keys do not expire at the same moment. Large key sets Small differences in cache freshness
Cache Warming Pre-loads frequently accessed keys before they expire. Predictable hot keys Requires identifying your most important cache entries

Mature caching solutions bundle these behaviors, so you configure them rather than build them by hand, which is why teams lean on managed edge caching instead of reinventing locking logic in every service.

Cache Locking and Request Coalescing

Cache locking, also called request coalescing or single-flight, lets only the first request rebuild an expired key while every other request waits for that single result instead of launching its own.

When a request finds an expired key, it tries to acquire a short-lived lock, often a Redis SETNX with a timeout. If it wins, it regenerates the value and writes it back. If it loses, it waits briefly and reads the freshly cached result.

Request coalescing is the in-process version of the same idea. If three hundred threads ask for the same missing key, the runtime lets one do the work and hands the answer to the other 299.

  • Request checks the cache and finds a miss on an expired key.
  • Request attempts to acquire a lock keyed to that cache entry.
  • The lock winner rebuilds the value and repopulates the cache.
  • Lock losers wait a short interval, then read the new value.
  • The lock is released or expires, and normal serving resumes.

You might worry the lock becomes a new bottleneck. In practice, the lock is held only for the rebuild duration of one request, so it converts thousands of duplicate rebuilds into exactly one, plus a few milliseconds of wait for the rest.

A ticketing platform added Redis single-flight locking around its seat-map cache. During an on-sale spike, origin queries for that key dropped from about 12,000 per minute to under 20, and database CPU fell from 95% to 22%.

Locking makes requests wait. The next approach makes them wait for nothing.

Stale-While-Revalidate and Randomized TTL in Practice

Stale-while-revalidate serves the expired value immediately while refreshing it in the background, and randomized TTL spreads expiration times so keys never all expire at the same instant.

With stale-while-revalidate, an expired entry is still returned to the user without delay. A single background task refreshes the cache, so no request waits on the origin, and the herd never forms.

Randomized TTL, or TTL jitter, adds a small random offset to each key’s lifetime. Instead of 500 keys all set to 3,600 seconds, you set each to 3,600 plus or minus a random 300 seconds. The expirations smear across a ten-minute window instead of detonating together.

  • Stale-while-revalidate: zero user-facing latency, brief staleness, ideal for feeds and pages.
  • Randomized TTL: prevents synchronized expiry at near-zero cost, ideal for large key sets.
  • Probabilistic early expiration: rebuilds a key slightly before its TTL based on rebuild cost, blending both ideas.

Pro Tip
For read-heavy pages, stale-while-revalidate is often the highest-impact improvement you can make. Users receive instant responses while the origin handles a single background refresh instead of a sudden request flood.

A SaaS dashboard applied 15% TTL jitter to 40,000 tenant-config keys. The nightly expiration spike that used to push database load to 80% flattened into a gentle ripple under 15%.

These techniques live in your application. A CDN moves the same protection to the edge, before requests ever reach you.

How CDN Architecture Helps Prevent Cache Stampede

A CDN prevents cache stampedes by caching content across many edge nodes and coalescing simultaneous misses into a single origin request, so your backend sees one fetch instead of a flood.

When a CDN edge node holds an expired object and many users request it, a well-designed CDN does not forward every request to your origin. It holds the extra requests, sends one upstream, and fans the fresh response back out to everyone waiting.

This origin shield or request-collapsing behavior turns a potential stampede into a single upstream call per edge location. Multiply that across a global network and the origin is insulated from concurrency it would otherwise absorb directly.

CDN Architecture Helps Prevent Cache Stampede

  • Request collapsing: many edge misses become one origin fetch.
  • Origin shield: a mid-tier cache layer further reduces origin hits.
  • Stale-while-revalidate at the edge: serve cached content while refreshing upstream.
  • Global distribution: expirations spread across regions instead of hitting one server at once.

For content-heavy or high-traffic sites, teams increasingly rely on a secure CDN for edge caching, because the collapsing and shielding behavior handles stampede protection without any application code changes.

This works because a global anycast network places cached copies close to users and spreads expirations across regions, while edge computing lets refresh logic run at the edge instead of round-tripping to your origin.

Pro Tip
Check whether your CDN enables request collapsing by default. Some providers require you to enable origin shielding manually, and without it, each edge node may still trigger a separate cache refresh and overwhelm your origin independently.

A news publisher moved breaking-story pages behind an edge cache with request collapsing. During a surge of 300,000 concurrent readers, the origin logged 41 requests for the lead article instead of the hundreds of thousands it would have seen unprotected.

One data store deserves its own section, because it is where most stampede questions actually start.

Redis Cache Stampede: Stopping It at the Data Layer

You stop a Redis cache stampede with a single-flight lock using SET with NX and a short expiry, or with probabilistic early expiration that rebuilds a key just before it expires.

Redis is the most common place stampedes appear because it is the default application cache for so many stacks. The upside is that Redis gives you the primitives to fix it directly.

The lock approach uses SET key value NX PX to grant one rebuild permit. The probabilistic approach, sometimes called XFetch, stores each value with its computation time and rebuilds early with a probability that rises as expiry approaches.

  1. On read, fetch the value and its remaining TTL.
  2. Compute a probability of early rebuild based on how expensive the value was to generate.
  3. If the probability triggers, one request rebuilds ahead of expiry while others keep serving the current value.
  4. The key is refreshed before it ever fully expires, so no synchronized miss occurs.

What most people miss with Redis: setting a very short TTL to fight staleness is exactly what creates the stampede. Probabilistic early expiration lets you keep a longer TTL while still refreshing often, the opposite of the reflex most engineers reach for.

A social app running a 30-second Redis TTL on trending topics switched to XFetch-style early recomputation. The synchronized 30-second miss vanished, and origin recomputes became smooth and evenly spaced.

Even with the right technique, a few habits quietly reintroduce the problem.

Common Mistakes That Reintroduce Cache Stampedes

The most common cache stampede mistakes are using uniform TTLs, setting TTLs too short, flushing the entire cache at once, and treating a single hot key like ordinary traffic.

  • Applying the same fixed TTL to every key guarantees synchronized expiration.
  • Shortening TTLs for freshness without adding locking or background refresh.
  • Flushing or restarting the whole cache during peak hours, creating a cold-start stampede.
  • Skipping request coalescing for the one or two keys that carry most of the traffic.
  • Relying only on the CDN while leaving the application cache unprotected behind it.

You might assume a big enough database can just absorb the spikes. Vertical scaling or load balancing buys headroom, but neither removes the pattern. The stampede still wastes compute on identical work, and the next traffic tier finds the ceiling again.

Pro Tip
Audit your cache for any key receiving more than a few hundred requests per second. These high-traffic keys, rather than average cache entries, are where cache stampede protection delivers the most value. Focus on protecting the critical few and avoid over-engineering the trivial many.

A fintech API protected 2,000 endpoints with locking but left its auth-token metadata key unguarded. That one key, hit 40,000 times a second, stampeded on every deploy until they wrapped it in single-flight caching.

Final Thought on Cache Stampede

A cache stampede is not a rare edge case. It is the predictable result of many requests needing the same value at the exact moment it disappears. The fix is never to hope your backend can take the hit. It is to make sure only one request does the rebuilding, or that no request has to wait at all.

Reach for the simplest layer that solves your case. Randomized TTLs desynchronize expirations for free, stale-while-revalidate removes user-facing waits, cache locking tames the single hot key, and an edge cache with request collapsing pushes the whole problem away from your origin. Combine them by traffic pattern rather than adopting one and calling it done.

Treat your hottest keys as the priority and design their expiration deliberately. Stable performance under load comes from controlling when and how cached data is rebuilt, not from adding raw capacity after an outage.

Frequently Asked Questions About Cache Stampede

What is the difference between the dogpile effect and a cache stampede?

There is no functional difference. Dogpile effect, thundering herd, and cache stampede are three names for the same event: many concurrent requests competing to regenerate the same expired value.

How do you fix a Redis cache stampede?

Use a single-flight lock with SET NX and a short expiry so one request rebuilds the key, or use probabilistic early expiration (XFetch) to refresh the key slightly before its TTL ends. Both stop the synchronized miss.

Does a CDN stop cache stampedes?

Yes, when it supports request collapsing and origin shielding. The CDN merges many simultaneous edge misses into a single origin fetch, so your backend sees one request instead of thousands during an expiration event.