Module 3 / Caching / Cache invalidation: the hard part

Lesson9 minModule 3 · lesson 5 of 10

Cache invalidation: the hard part

Removing or updating cached copies when the source changes, and the races that break it.

There is an old joke that computing has two hard problems, and cache invalidation is one of them. The reason is simple: the cache and the database are two places holding the same fact, and you must keep them in step without a transaction spanning both. TTL alone makes staleness bounded but not zero. Sometimes a user edits their delivery address and expects to see it immediately.

The usual approach on a write is to delete the cache entry rather than update it. Deleting is idempotent and cheap, and the next read refills from the database with the newest data. Updating the cache in place means two writers can race and leave the older value in the cache. Even delete-after-write has a subtle race, shown below.

A race that leaves stale data

Step 1 of 4

Reader misses

Reader A asks for user:7, finds nothing in the cache, and reads the database. It gets the old address.

Practical strategies, from simple to sophisticated: keep TTLs short for data that changes; delete the key on every write path (and make sure every writer does, including batch jobs and admin tools, which are the usual culprits); use versioned keys such as menu:42:v17 so a change creates a new key and the old one simply ages out; or publish change events from the database (change data capture) so a small service deletes affected keys no matter who made the change.

DatabaseChange logInvalidatorCachecommiteventdelete key
Change events can drive invalidation from the database's own log.
Question 1

Why do many systems delete the cache key on a write instead of updating it?

Question 2

Why keep a TTL even when you invalidate explicitly?

Your turn

List three different code paths that can change a restaurant's menu in your delivery app, and say what each must do to the cache.

Stuck? Think beyond the main API: batch imports, admin panels, background jobs.

What to remember

  1. The cache and database hold the same fact in two places; keeping them aligned is the hard part.

  2. Prefer deleting the key on writes, and make every write path do it.

  3. Races between slow readers and writers can leave stale entries, so keep a TTL as a safety net.

  4. Versioned keys and change events remove whole classes of invalidation bugs.