Caching
2 min read
Caching
A cache stores the result of an expensive operation so future requests are served fast from memory instead of recomputing or re-querying.
"There are only two hard things in computer science: cache invalidation and naming things." — Phil Karlton
Where caches live
- Client / browser — static assets, API responses.
- CDN — cached at the edge, near users.
- Application cache — Redis / Memcached between app and DB.
- Database cache — query and buffer pools.
Caching strategies
| Strategy | How it works | Best for |
|---|---|---|
| Cache-aside | App checks cache, on miss reads DB then fills cache | Read-heavy, general |
| Read-through | Cache library fetches from DB on miss | Clean app code |
| Write-through | Write to cache and DB together | Strong consistency |
| Write-back | Write to cache, flush to DB later | Write-heavy (risk of loss) |
Cache-aside in pseudocode
value = cache.get(key)
if value is null:
value = db.query(key)
cache.set(key, value, ttl=300)
return value
The hard parts
- Invalidation — stale data. Use short TTLs, or bust keys on write.
- Thundering herd — many misses hit the DB when a hot key expires. Use locks or staggered TTLs.
- Eviction — when full, drop the LRU (least recently used) entry.
A cache is an optimisation, not a source of truth. The system must still be correct if the cache is empty.