Skip to content

Read Strategies — Cache-Aside and Read-Through#

A read request comes in. The data might be in cache, or it might not. Who is responsible for fetching it from the DB on a miss — your application, or the cache itself?


Cache-Aside (Lazy Loading)#

The most common pattern. The application manages the cache manually.

Read request arrives
→ check cache
  → HIT  → return from cache ✓
  → MISS → app fetches from DB → app stores in cache → return

The application is responsible for both checking the cache and populating it on a miss. Data only gets cached when actually requested — lazy loading.

What's good:

Only caches what's actually needed  → no wasted memory on cold data
Simple mental model                 → app has full control
Cache failure doesn't break reads   → app can fall back to DB directly

What's bad:

First request always slow           → cold cache miss on every new key
Stale data possible                 → if DB is updated externally and
                                       cache isn't explicitly invalidated,
                                       old value stays until TTL expires

Classic example: Instagram feed — first load after a cache miss takes the full DB round trip. Every subsequent load is a cache hit and feels instant.


Read-Through#

The cache sits in front of the DB and handles misses automatically. The application only ever talks to the cache.

Read request arrives
→ goes to cache
  → HIT  → cache returns value ✓
  → MISS → CACHE fetches from DB → cache stores value → cache returns

The key difference from Cache-Aside: on a miss, it's the cache that fetches from the DB and populates itself — not your application code.

What's different from Cache-Aside:

Cache-Aside    → YOUR APP fetches DB on miss, populates cache
Read-Through   → THE CACHE fetches DB on miss, populates itself

What's good:

Cleaner application code   → app never calls DB directly for reads
Separation of concerns     → caching logic lives in the cache layer, not app

What's bad:

First request still slow         → miss is just handled by cache instead of app
Cache must know how to query DB  → more complex cache configuration
Less flexible                    → harder to apply custom logic on miss

When to use: systems where you want a clean abstraction between application and database — the app treats the cache as if it were the database.


Comparison#

Cache-Aside Read-Through
Who fetches on miss Application Cache itself
App complexity Higher (app handles miss) Lower (cache handles miss)
Cache complexity Lower Higher (needs DB connection)
Flexibility High Lower
Use when App needs control over miss logic Clean separation is priority