Caching and Performance Engineering · Caching Fundamentals
Cache-Aside, Read-Through and Write Patterns
The standard patterns for reading and writing cached data.
Cache-aside (lazy loading): the app reads the cache, loads from the database on a miss and populates the cache — the most common pattern. Read-through: the cache loads data itself via a loader. Write-through: writes update the cache and database together (fresh reads, slower writes). Write-behind: writes go to the cache and are flushed later (fast, but risk of loss). Write-around: writes skip the cache; it fills on read.
def get_product(id):
key = f"product:v2:{id}"
if (cached := redis.get(key)) is not None:
return json.loads(cached) # hit
product = db.fetch_product(id) # miss → source of truth
redis.set(key, json.dumps(product), ex=300 + random.randint(0, 30)) # TTL + jitter
return product
def update_product(id, data):
db.update_product(id, data) # 1. write the database (commit)
redis.delete(f"product:v2:{id}") # 2. invalidate (don't update) the cache
Common pitfalls
- Updating the cache instead of deleting it (race conditions leave stale values).
- Write-behind for data you can't afford to lose.
- No TTL as a safety net.
Key points
- Cache-aside is the default
- Delete on write, after commit
- TTL + jitter always
Further reading: AWS: Caching patterns
Practice questions
Why delete the cache key on update instead of writing the new value?
Answer
Concurrent requests can interleave so an older value is written after the newer one, leaving stale data cached; deletion forces the next read to load the current value.
When is write-behind acceptable?
Answer
For data where occasional loss is tolerable or recoverable (counters, analytics), and you need very high write throughput.
Open in the app to mark lessons complete, take notes and track your progress.