The Read-Through Cache Pattern: Let the Cache Manage Itself

2026-05-20

Most caching code looks the same and it's all wrong. The application checks the cache, misses, queries the database, writes to the cache, returns the result. That logic gets duplicated across every read path, and someone eventually forgets to populate the cache after a write. The read-through cache pattern fixes this by making the cache itself responsible for loading missing data.

The cache sits in front of the data source as a proper abstraction. Your application calls cache.get(key) and that's it. If the entry is present, it's returned. If not, the cache calls a loader function you registered at construction time, stores the result, and returns it. The application never sees the database miss — it just sees a slightly slower get.

Why this beats cache-aside:

Real example: A product catalog service was using cache-aside Redis lookups. When a hot SKU expired during a flash sale, 200 app instances all missed simultaneously and hammered Postgres with identical queries, taking down the database for 90 seconds. Switching to a read-through cache with Caffeine in front of Redis (two-tier) collapsed those concurrent loads into one per instance. The next expiration event produced exactly 200 DB queries instead of tens of thousands, and p99 latency stayed under 50ms.

Rule of thumb: If your cache hit ratio is H and you have N concurrent requests for the same key at the moment of expiry, cache-aside generates N DB hits while read-through with single-flight generates 1. At N=100 and 10 expirations/second on hot keys, that's the difference between 1,000 QPS of stampede traffic and 10.

The tradeoff: Read-through couples the cache to a loader, which means the cache library must support your data access pattern (sync, async, batch). It also hides slowness — a cache "get" can secretly do a 200ms DB query. Always set a load timeout and instrument loader latency separately from cache-hit latency.

Pair it with write-through or write-behind when consistency matters: writes go through the cache too, keeping it authoritative rather than guessing when to invalidate.

See it in action: Check out Roku Hidden Menu by Popo to see this theory applied.
Key Takeaway: Read-through caches own their loading logic, eliminating duplicated cache-miss code and giving you one place to add stampede protection.

All newsletters