Sobes.tech
Senior

How to handle a situation when all 5 goroutines simultaneously see an empty cache and go to the database (cache stampede)?

sobes.tech AI

Answer from AI

The cache stampede problem occurs when multiple goroutines simultaneously see that the cache is empty and all start querying the database, creating excessive load.

To prevent this, the following approaches can be used:

  1. Singleflight — in Go, there is the golang.org/x/sync/singleflight package, which allows grouping multiple concurrent requests with the same key into a single database request, while other goroutines wait for the result.
import (
    "golang.org/x/sync/singleflight"
)

var group singleflight.Group

func GetData(key string) (Data, error) {
    v, err, _ := group.Do(key, func() (interface{}, error) {
        // Check cache
        data, found := cache.Get(key)
        if found {
            return data, nil
        }
        // If not, load from DB
        data, err := db.Load(key)
        if err != nil {
            return nil, err
        }
        cache.Set(key, data)
        return data, nil
    })
    if err != nil {
        return nil, err
    }
    return v.(Data), nil
}
  1. Mutexes or channels — you can use a mutex on the cache key so that only one goroutine loads the data, and others wait.

  2. Cache warming — preloading the cache in advance to avoid situations where everyone sees an empty cache at the same time.

  3. Using TTL and random delays — to prevent all cache entries from expiring simultaneously.

The simplest and most effective method in Go is to use singleflight."}]}]}

How to handle a situation when all 5 goroutines… - sobes.tech