Contents

Backend Development › Caching

Read-Through Cache

The cache itself loads missing data from the database.

Also known as: read-through cache, read through cache, readthrough cache

A read-through cache sits in front of the source of truth and loads entries on a miss itself: the application asks the cache, and if the value isn’t there, the cache fetches it from the source, stores it, and returns it. The app doesn’t manage the load logic — the cache does.

app → cache.get(key)
        hit  → return value
        miss → cache loads from DB, stores, returns

It’s a variant of cache-aside, where the difference is who does the loading. In cache-aside, the application loads from the source and writes to the cache; in read-through, the cache library/component handles the load. Both leave the app code simple and keep misses from hitting the source repeatedly, but read-through centralises the load logic.

The classic mistakes:

  • Confusing read-through with write-through. Read-through is about loading on read. Writes need their own strategy — write-through or write-behind — or the cache goes stale after a write (see write-through cache).
  • Assuming it handles invalidation. Read-through fills on miss; it doesn’t automatically invalidate on update. You still need a write strategy and a TTL. Stale data after a write is the common result of a read-through-only cache.
  • Overlooking the miss cost cluster. On a miss, the cache queries the source; many simultaneous misses for the same key cause a stampede (see thundering herd). Single-flight/dedup within the cache helps.
  • Caching errors as values. If the load fails, storing the failure under the key poisons the cache. Distinguish “not found” (see negative caching) from “load failed”.
  • Ignoring key design. The read-through key must include everything that varies; a wrong key serves wrong data (see cache key design).
  • Assuming the library caches everything. Read-through only helps for keys you actually request and that fit the cache’s size/eviction; a miss-heavy access pattern gains little.

When to use it: when you want the cache to own the load logic and keep application code clean — common in caching libraries and ORM second-level caches. Pair it with a write strategy so updates don’t leave stale entries. It’s a convenience over plain cache-aside, and the correctness rules (keys, TTL, invalidation, stampede) are the same.