Script Valley
Redis: Complete Course
Caching PatternsLesson 3.3

Cache invalidation strategies: TTL, event-based, and tag-based invalidation

TTL-based invalidation, explicit delete on write, tag-based invalidation, cache key namespacing, versioned cache keys, invalidation fan-out problem

The hardest problem in caching

Phil Karlton famously said there are only two hard things in computer science: cache invalidation and naming things. Here are the three workable strategies.

TTL-based

Set a short TTL and accept brief staleness. Simplest approach โ€” no additional code on writes.

SET product:42 "{...}" EX 60   # stale for at most 60s

Event-based (explicit invalidation)

Delete or update the cache key whenever the underlying data changes.

async function updateProduct(id, data) {
  await db.update(id, data);
  await client.del(`product:${id}`);   // force cache miss
}

Tag-based invalidation

Group related cache keys under a tag. When data changes, delete all keys in that group.

// Store keys belonging to user:42's data
await client.sAdd('tag:user:42', 'user:42:profile', 'user:42:orders');

// On user update, invalidate all related keys
const keys = await client.sMembers('tag:user:42');
await client.del(keys);
await client.del('tag:user:42');

Tag-based invalidation adds complexity but is powerful when one data change affects many cache keys. Use event-based for simple cases and tag-based for objects with many derived cache entries.

Up next

Redis cache eviction policies: LRU, LFU, and allkeys explained

Sign in to track progress

Cache invalidation strategies: TTL, event-based, and tag-based invalidation โ€” Caching Patterns โ€” Redis: Complete Course โ€” Script Valley โ€” Script Valley