LESSON 7.2
Read and write patterns
Cache-aside, read-through, write-through, write-behind and write-around, with the trade-off each makes.
6 min read
"Add a cache" isn't a full design. You also need to say how reads fill the cache and what writes do to it. There are a handful of standard patterns; most systems use cache-aside for reads and choose deliberately for writes.
Cache-aside (lazy loading)
The application manages the cache itself.
- Read: look up the key in the cache.
- On a hit, return it.
- On a miss, read the database, store the value in the cache with a TTL, and return it.
- Write: update the database, then delete the cached key.
get(code):
link = cache.get(code)
if link is missing:
link = db.find(code)
cache.set(code, link, ttl = 1 hour)
return linkThis is the default because it's simple, the cache only holds data that was actually requested, and if the cache dies the system still works (just slower). Its weaknesses: the first read of every key is a miss, and there's a short window where a concurrent read can put a stale value back, covered in the next lesson.
Read-through
Same flow, but the cache library or service does the loading: the application only ever talks to the cache, which calls a loader on a miss. It keeps application code tidy and is common in in-process caches and some managed services. Behavior is otherwise similar to cache-aside.
Write patterns
Write-through
- Cache always holds the latest value
- Reads right after writes hit
- Every write pays for two stores
- Caches data that may never be read
Pick it when: Data read soon after it's written, such as a user's own profile.
Write-behind (write-back)
- Very fast writes
- Batches many updates into few database writes
- Recent writes are lost if the cache fails
- Complex
Pick it when: High-rate counters and metrics where small losses are acceptable.
Write-around
- Cache isn't filled with write-once data
- First read after a write misses
Pick it when: Data written often but read rarely, such as logs and uploads.
Delete, don't update
When data changes, the safest default in cache-aside is to invalidate (delete) the key rather than write the new value into the cache. Two concurrent writers updating the cache can finish in the opposite order from their database writes, leaving the older value cached indefinitely. Deleting means the next read loads whatever the database now holds.
Choosing in an interview
For most read-heavy designs: cache-aside for reads, update the database and delete the key on writes, with a TTL as a safety net. Mention write-through when users must see their own writes immediately, and write-behind only for data where losing the last few seconds is acceptable.
Try it
News Feed HLD
Cache feeds and counters for a read-heavy social product.