Caching Strategies
Caching strategies compared by read path, write path, and consistency tradeoffs.
Caching strategies are mostly about one question: where does truth live, and who is responsible for keeping the cached copy close enough to that truth? The answer affects latency, consistency, write durability, and failure behaviour more than the choice of cache product does.
The most common read pattern is cache-aside. The application looks in the cache first. If the key is present, the request is served quickly. If it is missing, the application reads from the database, returns the result, and stores it in the cache for next time. This is popular because it is simple and works with almost any datastore. The tradeoff is that the application now owns cache population and invalidation. If you forget to evict or refresh data after a write, users may keep seeing stale values until the TTL expires.
Read-through pushes that miss-handling logic into the cache layer. The application asks the cache for a key, and the cache fetches from the backing store when needed. That can reduce duplicate logic across services and make the cache look more like a storage tier. The cost is tighter coupling to the cache platform and less visibility into what happens on a miss. If the cache becomes slow or unavailable, the blast radius is larger because the read path depends on it more directly.
For writes, write-through updates the cache and the database in the same logical operation. The advantage is that hot keys stay warm and later reads are fast. The main cost is write latency, because the request is not complete until durable storage has accepted the change. Write-through also needs careful failure handling. If the cache write succeeds but the database write fails, or the reverse, your system needs a repair path.
Write-back, also called write-behind, acknowledges the write after the cache accepts it and flushes changes to the database later. This can dramatically improve write throughput for bursty workloads. It is useful when you can batch or coalesce many updates before they reach the backing store. The tradeoff is risk. A cache crash before flush can lose acknowledged data unless the cache itself has durable logging. This pattern is powerful, but only when the data model and operational controls can tolerate delayed persistence.
Write-around skips the cache during writes and updates only the database. This avoids filling the cache with data that may never be read again. It works well for write-heavy systems with low read locality. The downside is that the first read after a write is usually a miss, so users may pay the full database cost right after new data arrives.
The real difficulty in caching is not the steady state. It is the edge cases. Hot keys can overload a single shard. Cache stampedes can cause many clients to miss and hammer the database at once. Long TTLs reduce load but increase staleness. Short TTLs improve freshness but can erase much of the performance gain. Distributed invalidation is especially hard because writes and evictions may race across nodes.
A good strategy therefore matches workload shape. Use cache-aside for general-purpose application caching. Use read-through when you want a stronger caching abstraction. Use write-through when read latency matters more than write cost. Use write-back only when you understand the durability risk and have a safe flush path. Use write-around when the workload is write-heavy and most fresh writes are cold data. In every case, treat invalidation, TTLs, and failure recovery as first-class design work rather than small implementation details.