Caching Strategies
Cache-aside, read-through, write-through, write-back, refresh-ahead
Caching strategies define the contract between an application and its cache layer regarding when data is loaded, written, and invalidated. The five primary strategies — cache-aside, read-through, write-through, write-back, and refresh-ahead — trade consistency, complexity, and throughput against each other. Cache-aside (lazy loading) is the most widely deployed pattern, used by default in Redis integrations at companies like Uber, Twitter, and Shopify. Choosing the wrong strategy causes either stale reads, write amplification, or cache stampedes under load.
Key Points
- Cache-Aside (Lazy Loading): application checks cache first; on miss, reads from DB, populates cache, and returns — application owns cache population logic.
- Read-Through: cache sits in front of DB; on miss, the cache itself fetches from DB and stores result — application code is simpler but requires cache library support.
- Write-Through: every write goes to cache AND DB synchronously — strong consistency, higher write latency, no stale reads, wasted cache entries if data is never re-read.
- Write-Back (Write-Behind): write to cache immediately, async persist to DB — lowest write latency, risk of data loss if cache node fails before flush.
- Refresh-Ahead: proactively refresh cache entries before they expire based on access patterns — reduces miss spikes but can waste resources refreshing stale data.
- Cache stampede: multiple requests simultaneously miss the same cold cache key and hammer the DB — prevent with mutex locking, probabilistic early expiry, or background refresh.
- Cache warming: pre-populate cache at startup with hot data — critical for systems where a cold cache on deploy would cause database overload.
| Strategy | When to Use | Consistency | Complexity | Write Latency |
|---|---|---|---|---|
| Cache-Aside | General purpose, read-heavy workloads | Eventual (TTL-based) | Low | Normal (write bypasses cache) |
| Read-Through | Simplified app code, read-heavy | Eventual | Medium (cache must support it) | Normal |
| Write-Through | Strong consistency required, read-after-write | Strong | Medium | Higher (dual write) |
| Write-Back | Write-heavy, latency-sensitive (IoT, logging) | Weak (async flush) | High (flush orchestration) | Very Low |
| Refresh-Ahead | Predictable hot keys, low tolerance for miss latency | Eventual | High (prefetch logic) | Normal |
Real-World Example
Twitter's Timeline Service uses cache-aside with Redis for home timelines — on cache miss, a Fanout service reads from Manhattan (DB), hydrates the timeline, and populates Redis. Write-through is reserved for profile data where stale reads are unacceptable.