Module 3 / Caching / Cache stampede and the thundering herd

Lesson9 minModule 3 · lesson 6 of 10

Cache stampede and the thundering herd

What happens when a hot key expires and thousands of requests miss at once.

A cache protects the database only while entries are present. Consider the front page of your delivery app: one key, home:feed, read 10,000 times per second, rebuilt by a query that takes 200 ms. When that key expires, every request arriving in the next 200 ms misses, and each one starts the same expensive query. That is about 10,000 × 0.2 = 2,000 identical queries hitting the database at once. A database sized for the cached load can fall over, and slower responses mean even more concurrent misses. This is a cache stampede, or thundering herd.

10,000 req/sCache (key expired)Databaseall miss2,000duplicatequeries
When a hot key expires, all misses fall through together.

The root problem is that nothing coordinates the missers: each thinks it is the only one. The fixes all add coordination or remove the synchronised expiry. They can be combined, and which you pick depends on how expensive the rebuild is and how much staleness you can show.

Ways to prevent a stampede

Step 1 of 4

Single-flight / request coalescing

Inside one app server, the first request for a key starts the rebuild and the others wait for its result instead of querying. With 20 servers you still get up to 20 queries, not 2,000.

def get_feed():
    value, fresh = cache.get_with_soft_ttl("home:feed")
    if value is not None and fresh:
        return value
    if cache.set_if_absent("lock:home:feed", ttl=5):
        value = rebuild_feed()           # only one request does this
        cache.set("home:feed", value, ttl=60, soft_ttl=45)
        return value
    return value if value is not None else wait_and_retry()
Illustrative: one rebuilder, everyone else serves the old value.
Question 1

A hot key read 5,000 times per second takes 400 ms to rebuild. Roughly how many duplicate rebuilds can start when it expires and nothing coordinates them?

Question 2

How does serving stale data while refreshing in the background help?

Your turn

Your search results page has 50 popular queries cached with a 10-minute TTL, all filled at deploy time. What goes wrong at the 10-minute mark and how do you fix it?

Stuck? Think about everything expiring in the same second.

What to remember

  1. When a hot key expires, thousands of simultaneous misses can send duplicate expensive queries to the database.

  2. Coalesce or lock rebuilds so one request does the work.

  3. Serve stale while refreshing, refresh ahead of expiry, and add jitter to TTLs.

  4. Cold caches after restarts cause the same problem across all keys.