Stop 11 · CachingTopics · 6/8

Cache-Aside Pattern

Part of the Backend Developer Roadmap

In short

Cache-aside is the caching pattern you'll write most often. Check the cache, fall back to the database on a miss, then fill the cache for next time. Simple, with a few sneaky traps.

The most common caching pattern: your application checks the cache first, and on a miss, reads from the database and populates the cache for next time.

The blob character checks a pocket notebook after pulling a heavy book from a library shelf.

Think of it like this

Your own notes first

Before an exam, you check your own notebook first. If the answer is there, done. If not, you go to the library, find it in the big reference book, and copy it into your notes. Next time it's right there. Your notebook is the cache; the library is the database.

Watch it happen

Read path for user 7

App
Redis
Database

GET user:7

1/7The app checks Redis for user 7.

The big ideas

What you need to know

The app is in charge

The cache knows nothing about the database. Your code decides when to read, fill and delete.

Only cache what's asked

Entries appear only after someone reads them, so the cache holds data people actually request.

Delete on writes

When the data changes, delete the key. The next read refills it from the database.

Beware the stampede

When a hot key expires, hundreds of requests may hit the database at once. Share one loader between them.

See it in code

Walk through the code

ts
1const inFlight = new Map<string, Promise<unknown>>();2 3export async function cacheAside<T>(key: string, ttl: number, load: () => Promise<T>): Promise<T> {4  const hit = await redis.get(key);5  if (hit) return JSON.parse(hit) as T;6  if (!inFlight.has(key)) {7    inFlight.set(key, (async () => {8      try {9        const value = await load();10        await redis.set(key, JSON.stringify(value), { EX: ttl });11        return value;12      } finally { inFlight.delete(key); }13    })());14  }15  return inFlight.get(key) as Promise<T>;16}

1/3Step one of cache-aside: check Redis. A hit returns straight away.

This only shares loads within one process. Across many servers, a short Redis lock with SET key NX EX does the same job.

Save yourself the pain

Common mistakes

Oops

Not caching 'not found', so every request for a bad id hits the database.

Do this instead

Cache a small null marker with a short TTL for missing records, to stop repeated lookups.

Oops

Forgetting to delete the key when the record is updated.

Do this instead

Every write path for that data must delete its cache key, or readers see old data until the TTL ends.

Your mission

Survive a stampede

~35 min

Quick check

In cache-aside, who writes data into the cache?

Go deeper

  1. 1Implement cache-aside manually for one endpoint: check cache, miss, fetch, populate.
  2. 2Learn the 'thundering herd' problem when many requests miss the cache simultaneously.
  3. 3Compare cache-aside to letting your ORM or framework handle caching automatically.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge