Progress

    0%

    Write-Through vs Write-Back vs Cache-Aside

    Learning Objectives#

    • Distinguish the three write policies by what they do on a write and where the risk of inconsistency lives.
    • Trace the read and write path of each policy and name its typical failure mode.
    • Choose a policy for a workload and justify it in terms of consistency cost and throughput.

    Introduction#

    The previous article gave you the cache dials. This one is about the moment of writing: where does the new value go, first, second, and third. The three standard policies, write-through, write-back, and cache-aside, differ on which store owns the truth at any instant and how long a divergence between cache and database is allowed to survive. The policy is the contract for that window.

    Problem Statement#

    Your service updates a user's profile. You write to the database and, helpfully, also to the cache, in that order. The write fails after the database commit, or the order is reversed and the cache ends up holding a stale value. Either way, the next reader gets data that contradicts the database, and nobody knows which store to trust. The wrong policy makes the cache a source of quietly wrong reads. The fix is a policy that decides the truth order and the failure behavior on purpose.

    Core Concept#

    The three policies differ on what happens at write time.

    PolicyWrite doesRead that missesDivergence windowMain risk
    Write-throughwrites DB, then cachefill from DBnone on the writewrite latency, still stale on others
    Write-backwrites cache, flushes DB latercache or DBbetween flush and writedata loss on crash before flush
    Cache-asidewrites DB, invalidates cachefill from DBbriefrace between write and refill

    Write-through#

    Every write goes to the database and then immediately to the cache. Reads are always satisfied from the cache, because the cache is guaranteed to be as fresh as the database. The cost is that the write path now has two stops, which adds the cache latency to every write even when nobody reads that key. Write-through is honest but slow on the write, and it does nothing for the shared problem of a value written by a different route, because a second writer that bypasses the cache leaves it stale.

    Write-back#

    The write goes to the cache first, and the database receives it later, on a flush timer or when the cache evicts the key. The throughput is the best of the three because the write path is one stop and the database sees amortized batches. The risk is that the cache is now the only copy for a window, and a crash inside that window loses committed-to-cache writes. Write-back is for the systems where the throughput payoff exceeds the acceptable loss.

    Cache-aside#

    The read path fills the cache on a miss and reads the database otherwise. The write path updates the database and deletes the cached key. That delete is the subtle part: on the next read, the miss refills from the new database state. Cache-aside is the default and the correct default for most applications, because it never has to keep the cache and database in lockstep, it only needs to avoid a stale read between the delete and the refill.

    Diagram: read and write flow of the three cache policies.

    Write-through Write Cache first DB Write-back Write Cache holds write DB flush later Cache-aside Read Get key Cache DB miss fetch fill cache Write Write DB Cache delete key then When each fits Write-through: writes are rare, reads must be exact. Write-back: writes are frequent, loss is acceptable. Cache-aside: the default, delete key on write, refill on miss.

    What the table hides#

    The policies do not just differ in ordering; they differ in the type of inconsistency they tolerate. Write-through still goes stale when a second writer writes to the database without the cache, which is the common case in any system with two writer paths. Write-back accepts the full window of "cache has it, database does not," and the crash window is real. Cache-aside's failure is a specific race: a write deletes the key, then another writer writes a new value, and a concurrent reader misses, loads the old database row into the cache, and the cache now holds a value older than the just-committed one. That race is why cache-aside pairs with a TTL as a backstop.

    The default is cache-aside#

    For most applications the answer is cache-aside: database owns the truth, cache is a best-effort second copy, writes invalidate, reads fill. It is the policy with the fewest moving parts, and its failure mode, a transient stale read, is the cheapest to tolerate. Write-through is for the write path you want to guarantee fresh; write-back is for the write storm where batching buys the throughput. Naming the policy, and the window it tolerates, is the whole assignment.

    Real Production Usage#

    Spring's @Cacheable with a CacheManager is cache-aside in one annotation, and it only works if the paired @CacheEvict fires on the mutating method. Redis as the cache manager makes the read-miss-fill loop explicit. Write-back appears in systems where a local cache like Caffeine batches writes before a scheduled flush to a slower store. The production discipline is knowing which annotation half you wrote.

    Common Mistakes#

    1. Updating the cache instead of invalidating it. An update that races with another writer leaves the cache stale and the database correct, and you cannot tell which is true.
    2. Choosing write-back where a crash loses money. The flush window is the loss window, and a payments workload is the wrong place to trade it.
    3. Ignoring the cache-aside race. Without a TTL backstop, a racing refill can permanently lodge a stale value in the cache.

    Interview Perspective#

    Interviewers ask you to compare the policies and then to pick one for a workload. Weak: "write-through is safer." Strong: "cache-aside is the default because it deletes on write and refills on read, and I would take write-back only when batching pays for the loss window, never for money." They often probe the cache-aside race specifically to see if you know invalidation beats update.

    Follow-up: "What happens if the delete in cache-aside fails?" They want you to talk about the TTL backstop and the bounded staleness window.

    Knowledge Check#

    1. A write goes to the cache first and the database later. Name the policy, then name the disaster if the process dies before the flush.
    2. Cache-aside deletes on write instead of updating. Why is the delete better than the update in the presence of a racing reader?
    3. You pick write-through for a ledger. What does that cost on the write path, and what staleness does it still not protect you from?

    Key Takeaways#

    • Write-through, write-back, and cache-aside differ in the truth order and in the divergence window each tolerates.
    • Cache-aside is the default: DB owns truth, reads fill, writes delete, TTL backstops the race.
    • Choose write-back only when batching pays for a bounded loss window; never for money movement.

    What's Next#

    The right policy in hand, the remaining problem is that a cache is one tool among several, and the next article steps back to the whole persistence design. Persistence best practices is where the chapter's scattered decisions, fetch strategies, locks, transactions, and caches, get reconciled into a checklist you can apply to a real schema.

    Want to Master Spring Boot and Land Your Dream Job?

    Struggling with coding interviews? Learn Data Structures & Algorithms (DSA) with our expert-led course. Build strong problem-solving skills, write optimized code, and crack top tech interviews with ease

    Learn more

    Last updated on Aug 19, 2026

    Was it helpful?

    Subscribe to our newsletter

    Read articles from Coding Shuttle directly inside your inbox. Subscribe to the newsletter, and don't miss out.