Day 93: Redis caching patterns and invalidation
Redis: RAM-speed, by design
Redis keeps data in memory (Phase 0, Day 1's fastest tier short of CPU cache), which is precisely why it's ~100x faster than a disk-backed database for simple key lookups, and precisely why it's not meant to be your primary data store for everything — it's a cache and a fast structure server, layered in front of or alongside a durable database.
Caching patterns
- Cache-aside (lazy loading) — app checks cache first; on a miss, reads from the database and populates the cache. Simple, most common.
- Write-through — every write goes to the cache and the database together, keeping them always in sync at write time, at the cost of slower writes.
- Write-behind — writes go to the cache immediately and are asynchronously flushed to the database later; fast writes, but risk losing recent writes on a cache failure.
Invalidation: the hard part
"There are only two hard things in computer science: cache invalidation and naming things" is a joke with real teeth. A TTL-based expiry (Phase 2, Day 20's trade-off again) is simple but can serve stale data until expiry; explicit invalidation (deleting/updating the cache key exactly when the underlying data changes) is fresher but easy to miss an edge case and leave stale data indefinitely.
GET user:42
-> miss
SELECT * FROM users WHERE id=42 (from Postgres)
SETEX user:42 300 "{...serialized user...}" -- cache for 300s
-- Next request within 300s:
GET user:42 -> hit, no database round tripKey terms
- Cache-aside
- App checks cache first, falling back to the database on a miss and populating the cache.
- Cache invalidation
- Removing or updating cached data so it doesn't serve stale values after the source changes.
Why is Redis usually described as a cache/fast-structure layer rather than a replacement for a primary database?