A caching strategy is just the rule for who talks to the cache and when. The tricky part is never the reads — it’s keeping the cache and the database agreed on what’s true. Let’s walk the five patterns interviewers actually ask about.
Cache-aside (lazy loading)
The most common one by far. In simple language — the application manages the cache directly. The cache doesn’t know the database exists.
On a read: check the cache first. Hit? Return it. Miss? Load from the DB, stash a copy in the cache, return it. We only cache data that’s actually been asked for — hence “lazy loading”.
async function getUser(id) {
const cached = await cache.get(`user:${id}`);
if (cached) return JSON.parse(cached); // HIT
const user = await db.users.findById(id); // MISS → source of truth
await cache.set(`user:${id}`, JSON.stringify(user), "EX", 300); // 5 min TTL
return user;
}
When to use: read-heavy workloads where the app is happy owning the logic. Downside: the first read of anything is always a miss (a “cold cache”), and our code has to remember to keep the cache in sync on writes.
Read-through
Same read behaviour as cache-aside, but the cache does the DB fetch on a miss, not our app. We only ever talk to the cache; it’s the cache’s job to fill itself from the backing store.
The only difference from cache-aside is who loads on a miss — the cache library instead of our code. It keeps the app simpler, but we need a cache that supports it (a provider or a loader function).
Write-through
Now the writes. Write-through means every write goes to the cache and the database together, synchronously, before we tell the caller “done”.
The cache is always fresh — it can never be more stale than the DB, because they’re updated in the same breath. The price is a slower write: we pay two writes on the critical path.
Write-behind (write-back)
Same idea, but we cheat on timing. The write hits the cache and returns immediately. The cache flushes to the database later — batched, async, in the background.
Writes feel instant and the DB sees far fewer, bigger writes. The danger is obvious: if the cache dies before it flushes, those writes are gone. We trade durability for speed.
Write-around
The odd one out. On a write, we skip the cache entirely and go straight to the database. The cache only fills up later, on a read miss (cache-aside style).
Why bother? Because sometimes we write data that won’t be read again soon — logs, bulk imports, one-off records. Writing it into the cache would just evict genuinely-hot data for nothing. Write-around keeps the cache full of stuff people actually read.
When to use: write-heavy data with low re-read rates. Downside: a just-written record is a guaranteed miss if someone reads it right away.
Interview soundbite
Reads: cache-aside (app fills the cache) and read-through (cache fills itself) — same behaviour, different owner. Writes: write-through is safe but slow (cache + DB together), write-behind is fast but risky (cache now, DB later), and write-around skips the cache on writes to avoid polluting it with data nobody reads. Most systems run cache-aside for reads plus write-through or write-around for writes.