Caching

Lesson 6 of 14 · 24 min

x
43%

Cache Invalidation Strategies

Phil Karlton's famous quote still holds: cache invalidation is one of the two hardest problems in computer science. When the underlying data changes, stale cache entries must be removed or updated — otherwise users see outdated information. TTL (time-to-live) is the simplest strategy: every cached entry expires after a fixed duration. Set product cache to 5 minutes and stale data self-corrects. Event-based invalidation is more precise: when a product is updated, publish an event that tells every cache node to delete product:42. Versioned keys add a version number to cache keys (product:42:v3) — when data changes, bump the version and old entries become unreachable without explicit deletion. Stale-while-revalidate serves the stale value immediately while refreshing the cache in the background — users never wait, but may briefly see old data.

Before
TTL only — stale for up to 5 minutes
await redis.setex('product:42', 300, JSON.stringify(product));
// Product updated in DB at t=60s
// Cache serves stale data until t=300s
After
Event-based invalidation — immediate consistency
// On product update
async function updateProduct(id, data) {
  await db.products.update(id, data);
  await redis.del(`product:${id}`);
  await eventBus.publish('product.updated', { id });
}

// Other app instances also listen
eventBus.on('product.updated', ({ id }) => {
  localCache.delete(`product:${id}`);
});

Key Takeaway

TTL for simplicity, event-based invalidation for precision, stale-while-revalidate when availability beats freshness.

PreviousNext Lesson