Preventing Redis Cache Stampede with Mutex Locks: A Practical Guide

This article explains the cache‑stampede problem when hot Redis keys expire under massive traffic, illustrates why simple caching fails, and presents a mutex‑lock solution with Go code to safely rebuild caches while protecting the database.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Preventing Redis Cache Stampede with Mutex Locks: A Practical Guide

Cache stampede occurs when a hot Redis key is missing or expired while a large number of users simultaneously request it, causing a sudden surge of database queries that can overwhelm CPU and memory.

In my live‑room invitation leaderboard, we need to display the top 30 users who have invited the most participants in real time, which creates exactly this scenario.

Problem 1: The leaderboard must be up‑to‑date, so without caching we would have to query the database for every request.

Solution: Use a short‑lived cache (e.g., 30 seconds). After the cache expires, we query the database once, then repopulate the cache.

Problem 2: The naïve caching logic works under low concurrency but fails when many requests hit an expired key at the same moment.

ctx := context.Background()

rdb := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "123456",
    DB:       0,
})

redisKey := "xxx_xxx_xxx" // invitation leaderboard key

res, err := rdb.Get(ctx, redisKey).Result()
if err == nil {
    return res
}
// read DB (omitted) and obtain res
args := redis.SetArgs{TTL: time.Second * 30, Mode: "EX"}
_, _ = rdb.SetArgs(ctx, redisKey, res, args).Result()
return res

When traffic spikes—such as a popular live broadcast starting at 8 PM—thousands of users may hit the backend simultaneously. If the Redis cache for the leaderboard has just expired, all those requests fall through to the database, creating a classic cache‑stampede scenario.

Solutions:

Set the key to never expire – unsuitable because the leaderboard data changes frequently.

Manually refresh the key with a scheduled script – high maintenance cost and inflexible.

Use a mutex lock so that only one request rebuilds the cache while others wait or retry.

Below is a simplified Go implementation using a Redis‑based mutex:

ctx := context.Background()

rdb := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "123456",
    DB:       0,
})

redisKey := "xxx_xxx_xxx"
res, err := rdb.Get(ctx, redisKey).Result()
if err == nil {
    return res
}

// Acquire mutex
lockKey := "yyy_yyy_yyy"
argsLock := redis.SetArgs{TTL: time.Second * 3, Mode: "NX"}
_, err = rdb.SetArgs(ctx, lockKey, "1", argsLock).Result()
if err != nil {
    // Failed to get lock, retry reading cache a few times
    for i := 0; i < 3; i++ {
        res, errRetry := rdb.Get(ctx, redisKey).Result()
        if errRetry == nil {
            return res
        }
        time.Sleep(10 * time.Millisecond)
    }
    return nil // still no data
}

// At this point we hold the lock – read DB (omitted) and obtain res

// Rebuild cache and release lock
args := redis.SetArgs{TTL: time.Second * 30, Mode: "EX"}
_, _ = rdb.SetArgs(ctx, redisKey, res, args).Result()
rdb.Del(ctx, lockKey)
return res

This approach mitigates cache stampedes, but it is not flawless; if the lock‑holding goroutine crashes before resetting the cache, other requests may repeatedly fail and eventually return an empty result.

Feel free to think about the remaining edge cases and possible optimizations.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceredisGoMutex LockCache Stampede
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.