User Tools

Site Tools


skills:cache

This is an old revision of the document!


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โ€

Sequence Diagram

 Client A Go API DB Redis | | | | |---update A--->| | | | |---UPDATE--->| | | |<--OK--------| | | |---SET A------------------->|

Client B Go API DB Redis
| | | |
|---update B--->| | |
| |---UPDATE--->| |
| |<--OK--------| |
| |---SET 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

skills/cache.1779778674.txt.gz ยท Last modified: by phong2018