This is an old revision of the document!
Table of Contents
Cache Invalidation Patterns in Real Production Systems
Overview
Cache invalidation ensures cached data stays consistent with the database in distributed systems.
In real production systems, the hardest problem is:
Handling concurrency and distributed timing while keeping cache consistent with DB.
Most systems use a combination of patterns, not a single approach.
1. Cache-Aside (Most Common Pattern)
Concept
Application manages cache manually. Cache is a read-through optimization layer, DB is the source of truth.
Read Flow
Client โ Application โ Cache โ miss Database โ Cache โ Response
Write Flow
Client โ Application โ Database update โ delete cache key
Where it is used
Microservices systems E-commerce platforms Social applications
Pros
Simple Safe Easy to debug Flexible
Cons
Cache miss causes DB hit Small stale window possible
2. Write-Through Cache
Concept
Write goes through cache first, then DB.
Flow
Client โ Cache โ Database
Pros
Strong consistency No stale cache
Cons
Slower writes Higher cost
3. Write-Behind Cache
Concept
Write goes to cache first, DB updated asynchronously.
Flow
Client โ Cache (ACK) โ async Database
Pros
Very fast writes High throughput
Cons
Risk of data loss Complex recovery
4. TTL-Based Invalidation
Concept
Cache expires automatically after time.
Example
user:123 โ TTL = 5 minutes
Pros
Simple Safe fallback
Cons
Stale data until expiration
5. Event-Driven Invalidation
Concept
Database changes emit events to invalidate cache.
Flow
Service โ Database update โ Event (UserUpdated) โ Cache Service โ delete/update cache
Pros
Decoupled systems Scalable
Cons
Eventual consistency Event delay or loss possible
6. Update-on-write vs Invalidate-on-write
๐ฅ 6.1 Update-on-write (RISKY under concurrency)
Problem
Concurrent updates can cause race conditions between DB and cache.
Scenario
Request A updates value = โAโ Request B updates value = โBโ
Problem
If execution order is mixed:
DB = B Cache = A โ
Conclusion
Update-on-write is unsafe due to:
Race conditions Out-of-order execution Distributed timing issues
๐ฉ 6.2 Invalidate-on-write (SAFE pattern)
Concept
Do NOT update cache. Only delete it.
Sequence Diagram
Client A Go API DB Redis | | | | |---update A--->| | | | |---UPDATE--->| | | |<--OK--------| | | |---DEL--------------------->| Client B Go API DB Redis | | | | |---update B--->| | | | |---UPDATE--->| | | |<--OK--------| | | |---DEL--------------------->|
Why it is safe
Only DELETE operations on cache No stale value can be written
Read Flow
Client โ Redis (miss) โ Database โ Set cache
Always consistent with DB.
7. Comparison Table
| Aspect | Update-on-write | Invalidate-on-write |
|---|---|---|
| Cache operation | SET | DELETE |
| Race condition risk | โ High | โ Low |
| Out-of-order updates | โ Dangerous | โ Harmless |
| Cache correctness | โ Fragile | โ Reliable |
| Debug complexity | High | Low |
8. Key Insight
Cache is not the source of truth.
DB = source of truth Cache = disposable optimization layer
Invalidate-on-write works because:
Even if cache is wrong, it will be deleted anyway.
9. Production Pattern
Most systems use:
WRITE: 1. Update Database 2. Delete Cache READ: Cache hit โ return Cache miss โ DB โ set cache
10. Why Update-on-write still exists
Used only in limited cases:
Simple data Low concurrency Ultra-fast read-after-write requirement
Examples:
Session storage Feature flags Simple counters
11. Bonus Topics
Cache stampede problem Mutex / singleflight Request coalescing Kafka-based cache invalidation Outbox pattern for reliability
