Skip to main content

Four Redis Caching Strategies and When to Avoid Them

1 min read

The spectrum

StrategyRead perfWrite perfStaleness riskComplexity
Cache-asideHighHighMediumLow
Read-throughHighMediumLowMedium
Write-throughMediumLowNoneMedium
Write-behindMediumHighHighHigh

Cache-aside (our default)

Application checks cache first, falls back to DB, populates cache.

func GetUser(ctx context.Context, id string) (*User, error) {
    if user, err := cache.Get(ctx, "user:"+id); err == nil {
        return user, nil
    }
    user, err := db.GetUser(ctx, id)
    if err != nil {
        return nil, err
    }
    cache.Set(ctx, "user:"+id, user, 5*time.Minute)
    return user, nil
}

Works until you have a thundering herd on cache miss.

Write-behind (the one that bit us)

Batching writes to Redis then flushing to DB asynchronously. Great for write-heavy workloads. Terrible when the flush fails silently and you lose data.

What I learned

Start with cache-aside. Only reach for the others when you have a measurable problem — not because you anticipate one. Write-behind in particular should come with a monitoring dashboard before it goes to production.