Cache Strategies: Aside, Write-Through, Write-Behind
Cache-aside: app reads from cache; on miss, loads from DB and populates cache. Write-through: writes go to cache and DB synchronously. Write-behind (write-back): writes go to cache immediately, then async to DB.
Cache-aside = checking your sticky note before calling the office. Write-through = updating the sticky note AND the master file at once. Write-behind = scribbling a note now and filing it later (hope the sticky doesn't fall off).
Cache-aside is the most common pattern: lazy population, app controls the cache, works with any DB. Downside: cold start (empty cache on first load), write operations bypass cache causing inconsistency until TTL expires. Write-through keeps cache and DB consistent at the cost of higher write latency (both cache and DB must acknowledge). Write-behind optimizes write throughput (write returns after cache write) but risks data loss if the cache fails before async DB write completes — suitable for analytics/logging, not financial data.
Cache-aside with TTL creates a consistency window: stale data is served for up to TTL seconds after a DB write. To reduce this, use cache invalidation on write: after updating the DB, delete the cache key (not update it — delete forces a cache miss and fresh DB read on next access, avoiding race conditions where a slow cache write overlaps a DB write). Cache invalidation is hard: the classic approach is 'write to DB first, then delete cache key' — if the cache delete fails, the stale entry expires via TTL. For read-heavy systems with complex computed values (e.g., user feed), consider a 'read-through' cache where the cache itself fetches from the DB on a miss, giving you a centralized caching layer.
My default is cache-aside with explicit invalidation. On any write, I update the DB first, then delete the cache key (not update it). Deletion is safer than update because it avoids race conditions. I use TTL as a safety net, not the primary invalidation mechanism. For write-heavy paths where DB write latency is the bottleneck, write-behind with a durable queue (Kafka) between cache and DB gives me fast writes with eventual DB consistency — acceptable for non-critical data.
Updating the cache after a DB write instead of deleting it. A concurrent reader may be about to write a stale value to the cache at the same moment, causing the fresh value to be immediately overwritten. Delete forces a clean miss; update creates a race window.