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.