Caching Strategies
Caching 101 covered the basic hit/miss mechanism; a caching strategy is the answer to the two questions that mechanism leaves open — who's responsible for populating the cache, and when does a write update it? Different strategies answer those questions differently, and the choice has real consequences for staleness, latency, and what happens if the cache goes down.
Cache-aside (lazy loading)​
The application code owns the cache directly: on a read, check the cache first; on a miss, read from the database, then write the result into the cache for next time. On a write, the application updates the database and either updates or (more commonly) simply invalidates the corresponding cache entry.
Cache-aside is the most common pattern precisely because it's forgiving: if the cache is empty or unreachable, reads still work (just slower, falling through to the database every time), and only keys that are actually requested ever get cached — there's no work spent pre-populating data nobody asked for.
Write-through​
Every write goes to the cache and the database together, as one logical operation, before being acknowledged. The cache is always up to date immediately after a write, which removes the staleness window cache-aside leaves between a database write and the next cache population — at the direct cost of adding the cache's write latency to every write, and of caching data that might never actually be read again.
Write-behind (write-back)​
The write goes to the cache immediately and is acknowledged right away; the cache asynchronously flushes it to the database shortly after. This gives the lowest possible write latency, since the caller doesn't wait on the database at all — but it means a cache failure between the write and the flush can lose data that was already acknowledged as durable, which is a real correctness risk that has to be weighed against the latency win. This is the same durability-vs-latency shape as asynchronous vs. synchronous Data Replication: acknowledging early is faster and riskier, acknowledging late is slower and safer.
Read-through​
Structurally similar to cache-aside, but the cache itself (not the application) is responsible for loading from the database on a miss — the application only ever talks to the cache. This centralizes the miss-handling logic in one place instead of every caller reimplementing it, at the cost of needing a cache layer that actually supports this (most simple key-value caches don't, out of the box; it's more a feature of caching frameworks and some managed services). The full compare of read-through against write-through gets a dedicated tradeoff writeup in Read-Through vs. Write-Through Cache.
Picking a strategy: what's the write pattern?​
| Strategy | Write latency | Staleness risk | Best for |
|---|---|---|---|
| Cache-aside | Normal (DB only) | Between a write and the next read that repopulates | General-purpose, most common default |
| Write-through | Higher (cache + DB) | Minimal — cache always current | Data read immediately after being written |
| Write-behind | Lowest | Data loss risk on cache failure | Very write-heavy, latency-critical paths |
| Read-through | Normal (DB only, via cache) | Same as cache-aside | Centralizing miss-handling in the cache layer |
The practical decision usually comes down to how the workload writes: cache-aside is the safe default for read-heavy, occasionally-written data; write-through earns its extra write cost when a write is almost always followed by a read of the same data soon after; write-behind is reached for specifically when write latency is the bottleneck and the data can tolerate a small window of risk.
TTLs: the simplest invalidation strategy of all​
Independent of which strategy populates the cache, most cached entries also carry a time-to-live (TTL) — an expiration after which the entry is treated as a miss regardless of whether it was explicitly invalidated. A TTL is a blunt but effective tool: it bounds the worst-case staleness window without requiring the write path to know about (or reliably invalidate) every cache entry that might be affected by a change, at the cost of occasionally serving stale data for up to the TTL's duration, and occasionally causing an avoidable miss for data that hasn't actually changed.
Why this matters in an interview​
Naming the specific strategy — "cache-aside, since reads vastly outnumber writes here" or "write-through, since a user needs to see their own write reflected immediately" — is a concrete, defensible design decision. It's also worth proactively naming the staleness window each strategy leaves open, since that's usually the detail an interviewer is actually probing for when they ask "what if the underlying data changes?"
Cache-aside vs. write-through: pros and cons​
Cache-aside
- Only caches data that's actually requested — no wasted cache space
- Reads still work (just slower) if the cache is empty or down
- Simple to add on top of an existing database without changing the write path
Write-through
- Adds cache-write latency to every database write, even ones never read again
- Caches data speculatively, which can waste space on entries that go unread
- Still needs a separate eviction/TTL policy — being "always fresh" isn't "always small"
Further Reading​
- AWS — Caching strategies — a practical breakdown of cache-aside, write-through, and write-behind with concrete guidance on when to use each.
- Redis Docs — Caching patterns — implementation-level detail on how these patterns are actually built against a real cache.
Saved locally in your browser — visible in the sidebar as you go.