Chapter 35: Caching Patterns — Read-Through, Write-Behind

Caching reduces database load by serving frequently-accessed data from fast storage (Redis, in-memory). But cache invalidation is one of the hardest problems in computer science.

Cache-Aside (Lazy Loading)

1. App checks cache: GET user:123 2. Cache MISS → query database 3. Store result in cache: SET user:123 (with TTL) 4. Return to client Next request: 1. App checks cache: GET user:123 2. Cache HIT → return immediately (no DB query)
// Pseudocode: cache-aside pattern
user = cache.get("user:123")
if user == nil {
    user = db.query("SELECT * FROM users WHERE id=123")
    cache.set("user:123", user, ttl=300)  // 5 min TTL
}
return user

Write-Through

Write to cache AND database simultaneously. Cache is always up-to-date.

// Write-through: update both
db.update("UPDATE users SET name='Bob' WHERE id=123")
cache.set("user:123", updated_user)  // cache always fresh

Write-Behind (Write-Back)

Write to cache first, asynchronously flush to database later. Fast writes but risk of data loss if cache crashes.

Cache Invalidation Strategies

StrategyHowTrade-off
TTL (Time-To-Live)Cache expires after N secondsSimple but stale data for up to TTL
Event-basedInvalidate on write (pub/sub)Fresh but complex
Version-basedInclude version in cache keyNever stale but more cache misses

Common Pitfalls

⚠️ Cache Problems
Key Takeaways