Free — no signup required

Cache Invalidation Patterns

2 min read

The Hardest Problem in Computer Science

Phil Karlton famously said: "There are only two hard things in Computer Science: cache invalidation and naming things." Cache invalidation — deciding when cached data is no longer valid and must be refreshed — is genuinely difficult because it requires coordinating two systems (cache and database) that can diverge.

Pattern 1: TTL-Based Expiration (Passive Invalidation)

The simplest approach: set a TTL on every cached key. When it expires, the next request fetches fresh data from the database and repopulates the cache.

Pros: Simple to implement. No coordination required between cache and database.
Cons: Data can be stale for up to TTL duration. Short TTLs increase database load; long TTLs increase staleness.

Best for: Data where slight staleness is acceptable (product listings, public content, analytics).

Pattern 2: Write-Through Cache

On every database write, the application also writes the updated value to the cache simultaneously.

write_to_db(key, value)
write_to_cache(key, value, ttl=3600)

Pros: Cache is always consistent with the database. No stale reads.
Cons: Write latency increases (two writes per operation). Cache fills with data that may never be read (write amplification).

Best for: Workloads where read consistency is critical and write volume is manageable.

Pattern 3: Cache-Aside (Lazy Loading)

The application checks the cache first. On a miss, it reads from the database and populates the cache. On a write, it invalidates (deletes) the cache key rather than updating it.

# Read path
value = cache.get(key)
if value is None:
    value = db.query(key)
    cache.set(key, value, ttl=300)
return value

# Write path
db.update(key, new_value)
cache.delete(key)  # Invalidate, don't update

Pros: Cache only contains data that's actually been requested. Resilient to cache failures (app falls back to DB). Deleting is safer than updating (avoids race conditions).
Cons: First request after invalidation always hits the database (cold start). Race condition possible between delete and a concurrent read populating stale data.

Best for: Most general-purpose caching. The most widely used pattern in production.

Pattern 4: Write-Behind (Write-Back)

The application writes to the cache immediately and returns success. A background process asynchronously flushes cache writes to the database.

Pros: Extremely low write latency (write to RAM, return immediately).
Cons: Risk of data loss if cache fails before flush. Complex to implement correctly. Not natively supported by ElastiCache — requires application-level implementation.

Best for: High-frequency write workloads where some data loss is tolerable (analytics counters, game state).

This is one of 18 chapters

Get every chapter — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

See pricing