Caching Strategies

Improving performance with cache-aside, write-through, and CDN patterns to reduce load on databases.

IntermediateCachingChapter: Caching Infrastructure16 min read

What It Is

Caching stores frequently accessed data in a fast, temporary storage layer (usually RAM or edge servers) so you do not hit the slower, authoritative storage layer (databases or disk files) on every request.

The right caching strategy depends on your read-to-write ratio, data consistency requirements, and latency thresholds.


Caching Topologies

Three Common Caching Topologies

1. Cache-Aside (Lazy) App checks cache first On Miss: reads from DB, writes back to cache, and returns data.

2. Write-Through Synchronous double-write App writes to cache AND database in one transaction before ack.

3. Write-Behind (Async) Asynchronous write App writes to cache, acks client immediately. Queue updates DB later.

App Cache (Redis) Database 1. Read (Miss) 2. Fetch from DB 3. Write to cache

1. Cache-Aside (Lazy Loading)

The most common approach: the application coordinates reads and writes.

  • Read flow: App checks the cache. On a hit, it returns the data. On a miss, it reads from the database, populates the cache, and returns.
  • Write flow: App updates the database directly and invalidates (deletes) the cached entry.
  • Pros: Cache only contains requested data; database failures do not break the whole application.
  • Cons: Three round-trips on a cache miss; stale data if writes bypass the application.

2. Write-Through

The application treats the cache as the main data store.

  • Read flow: Same as cache-aside (or managed directly by the cache layer).
  • Write flow: When data is updated, the app writes to the cache, and the cache synchronously writes to the database. The write completes only after both succeed.
  • Pros: Data is never stale; read path is fast.
  • Cons: High write latency; many unused keys fill up cache memory.

3. Write-Behind (Write-Back)

An asynchronous write topology.

  • Write flow: The application writes to the cache, which immediately acknowledges success. A background queue or worker asynchronously flushes the modifications to the database.
  • Pros: Incredible write performance; buffers database write bursts.
  • Cons: Risk of data loss if the cache crashes before flushing; eventual consistency challenges.

Production Concerns

1. Cache Stampede (Thundering Herd)

A cache stampede occurs when a high-traffic key expires. If 1,000 concurrent requests arrive for user:1001 at the same microsecond and find a cache miss, all 1,000 requests will hit the database to calculate or query the same data.

Solutions:

  • Mutex Locks (Single Flight): Use a lock to ensure only the first request queries the database. Subsequent requests wait for the lock and read from the newly populated cache.
  • Probabilistic Early Expiration: Background workers regenerate the cached value before it actually expires based on request probability.
  • Soft Expiration (Stale-While-Revalidate): Return the expired value to clients while fetching the new value in the background.

2. Cache Invalidation

Deciding when to expire data is the hardest problem in caching.

  • TTL (Time to Live): A timer set on each key. When the timer expires, the key is removed. Essential to prevent permanent memory bloat.
  • Active Invalidation: Explicitly deleting the cache key whenever a write or delete occurs in the primary database.

Cache Eviction Policies

When the cache memory limits are reached, the system must drop old keys to make room for new ones.

Policy Name Logic Best Use Case
LRU Least Recently Used Drops the key that has not been accessed for the longest time General purpose, default for Redis
LFU Least Frequently Used Drops the key with the lowest hit counter Popular items (e.g. static homepage assets)
FIFO First In, First Out Drops the oldest key, regardless of hits Time-series or sequential logs
Random Random Eviction Drops keys completely at random Low overhead, simple datasets

Further Reading

Code Examples