Developer Tools

Database Caching: Cache-Aside, Read-Through and Write-Through

Compare read and write paths, then design invalidation, outage behavior and stampede protection around your freshness requirements.

AiFolder Editorial Team

AiFolder Editorial Team

5 min read

Updated Oct 9, 2026

A red fast-access drawer near the viewer linked to a larger deep charcoal archive cabinet, one luminous ceramic data sphere moving between levels
Original AiFolder editorial illustration

A cache is a copy with a freshness policy

Caching helps repeated reads avoid expensive work. The hard part is deciding when the copy becomes stale and what to do when it cannot be trusted. Start by defining whether a product description can be minutes old and whether a permission decision must reflect a revocation immediately. Those two answers may require different paths.

Compare the data flows

Strategy Read path Write path
Cache-aside Application checks cache, loads on miss Application updates database and invalidates
Read-through Cache abstraction invokes a loader Separate policy defines invalidation
Write-through Reads use the cache Write path coordinates cache and durable store
Write-behind Reads use the cache Durable persistence happens asynchronously

The labels do not specify atomicity. A write-through wrapper still needs a policy if one of its writes fails. Write-behind adds an explicit durability risk window. Microsoft's cache-aside guide discusses consistency and suitability.

A product price changes while an old read is in flight

A catalog endpoint reads a product from the database after a cache miss. While that read is in flight, an administrator changes the price and the update path invalidates the cached entry. The original reader then finishes and stores the old value in the cache. Invalidation happened, yet customers can still see a stale price. This race is why a cache diagram needs timing and an explicit correctness boundary, not only a database arrow and a cache arrow.

For checkout, validate the authoritative price and inventory inside the operation that creates the purchase. The catalog cache may be allowed to show a slightly older display value, but it should not authorize a charge. Versioned values, bounded expiration and carefully designed invalidation can reduce stale reads; their complexity should match the feature's tolerance. Keep the original record revision with cached data where useful. That makes a suspected stale response traceable to a source version instead of leaving operators to guess whether the cache, replication or client browser is responsible.

A product price changes while an old read is in flight: Read old row → Commit new price → Invalidate cache → Late fill
A product price changes while an old read is in flight. Original AiFolder explanatory diagram; illustrative workflow.

Pick a policy per data type

A public product description and an account balance deserve different policies. Cache-aside gives application code control over misses and lets the database remain usable if the cache is down. That flexibility also makes key design, eviction and invalidation application responsibilities. Read-through moves loading into a cache layer or library, which can simplify callers but introduces a component whose behavior every service must understand. Write-through reduces some read-after-write gaps only if failures across the write path are handled deliberately.

Specify expiration, maximum object size and negative-cache behavior for each data family. A missing product cached for too long can hide a newly created item. A shared key that omits tenant, locale or permissions can return the wrong content even with a perfect hit ratio. Avoid interpreting a high hit rate as proof of correctness. The useful comparison includes stale-value tolerance, fallback behavior, memory pressure and write amplification. For a small hot lookup table, a simple bounded cache can be valuable; for a security decision, extra freshness complexity may outweigh the latency saved.

Pick a policy per data type: Cache-aside → Read-through → Write-through → No cache
Pick a policy per data type. Original AiFolder explanatory diagram; illustrative workflow.

Example: an article cache

A request checks article:42. On a miss it loads the published row, stores a bounded copy and returns it. Publishing a revision updates the canonical row and invalidates the cached entry. Include a content version or deployment namespace when changing serialized shapes, so a new application does not misread an old payload.

Invalidation has races. A slow reader can load the old row, pause, then populate the cache after a writer has already invalidated it. Possible responses include version checks, a second invalidation, shorter retention, or bypassing the cache for workflows requiring immediate correctness. Choose the response from the invariant, not from a slogan.

Stampedes and outages

When a popular key expires, many requests can load the same record simultaneously. Single-flight coordination, randomized expiry and bounded stale-while-refresh behavior can reduce duplicate work. Each has a failure policy: a lock owner can disappear and stale data can outlive its intended window.

If Redis fails, unlimited fallback requests can overload the database. Put a concurrency budget on origin loads and define when to shed work. Redis's cache-aside guide documents the core flow; numerical latency claims there are vendor guidance rather than measurements of your application.

Verify what users observe

Exercise a cache hit, miss, edit, deletion, simultaneous expiry and cache outage. Inspect the returned revision as well as timing. Track hit rate, origin load, eviction and stale response age. A high hit rate is not success when the cached answer is wrong.

Continue with distributed locks for cooperative ownership and scalability bottlenecks for deciding whether caching addresses the measured problem.

Prevent a cold-cache outage from becoming a database outage

When many entries expire together, thousands of application requests may all fall back to the database. A cache restart can create the same situation. Use bounded request coalescing for a hot key and stagger expirations where appropriate. Put explicit concurrency limits on fallback work so that a cache failure does not turn into uncontrolled primary-database load. Timeouts should be short enough to release resources, but retries must not multiply the same expensive lookup indefinitely.

Measure miss traffic, fill duration, evictions and stale-data incidents separately. The hit ratio can remain attractive while a small set of expensive misses dominates latency. During recovery, warm only the keys justified by observed demand or a controlled priority list; loading the entire database into the cache can prolong the outage. Rehearse empty-cache behavior with representative request patterns and verify that essential operations still work within a defined degraded budget. The invariant is that losing the cache reduces performance in a controlled way while the authoritative data and its business rules remain intact.

Prevent a cold-cache outage from becoming a database outage: Cache misses surge → Coalesce requests → Bound fallback → Restore gradually
Prevent a cold-cache outage from becoming a database outage. Original AiFolder explanatory diagram; illustrative workflow.

Further reading for these examples

Topics

AiFolder Editorial Team

Written by

AiFolder Editorial Team

Practical technology guides with clear sources, examples and limitations.

Continue reading

More articles

View all