Skip to main content

Caching Strategies — Where and When to Write

The position of cache relative to your DB and the direction of writes determines consistency, complexity, and performance.

When to use

  • Cache-aside: most common, general purpose — app controls all cache logic
  • Write-through: cache and DB always in sync, at cost of write latency
  • Write-behind: write-heavy workloads tolerating async DB persistence

Tradeoffs

  • Write-behind risks data loss on cache crash before async write completes
  • Write-through doubles write latency (cache + DB in the same request)
// Cache-aside: check cache, on miss fetch from DB, populate cache
func GetUser(ctx context.Context, id string) (*User, error) {
cached, err := redis.Get(ctx, "user:"+id).Result()
if err == nil {
var u User
json.Unmarshal([]byte(cached), &u)
return &u, nil
}

user, err := db.QueryUser(ctx, id)
if err != nil {
return nil, err
}

data, _ := json.Marshal(user)
redis.Set(ctx, "user:"+id, data, 5*time.Minute)
return user, nil
}

Gotcha: Cache-aside is lazy loading. Cache flush + high traffic = thundering herd on your DB. Use probabilistic early expiry or request coalescing.