advanced26 min studyLesson 326 in Engineering

Write paths and cache-aside races

Specify acknowledgment and recovery semantics before comparing write-through, write-back, and cache-aside patterns.

On this page

What you’ll understand

  • Distinguish write acknowledgment from durable origin persistence.
  • Trace a stale cache-aside fill that races a committed update.
  • Explain why delete-after-write needs stronger coordination for strict freshness.

Naming a cache pattern does not specify what an acknowledged write survives or which value a concurrent read observes. Write-through, write-back, and cache-aside describe where work is placed, while correctness depends on ordering, failure recovery, and the source of truth. Write down the acknowledgment boundary and a concurrent timeline before optimizing away a database operation. A fast success response can hide an unpersisted update or a stale refill.

The acknowledgment boundary defines the promise

In a write-through design, a write passes through a caching layer toward backing storage, but exact acknowledgment and atomicity still depend on the implementation. Do not assume that two systems update transactionally merely because the application calls them in sequence. If the origin commits and the cache update fails, choose whether to invalidate, retry, or tolerate a bounded stale entry. A successful response should match the documented durability and visibility contract, including crash behavior.

Write-back or write-behind can acknowledge before the authoritative destination has received the update. The intervening dirty state therefore needs a durable queue or log if acknowledged writes must survive failure. Ordering, deduplication, retries, and replay determine whether a restarted worker can safely drain that state. Evicting a dirty entry is not equivalent to evicting a disposable read replica. Capacity planning must include undrained changes and their failure semantics, not just ordinary cache values.

Ddirty(t)=Ddirty(0)+∫0t(raccept(u)−rpersist(u)) duD_{\rm dirty}(t)=D_{\rm dirty}(0)+\int_0^t\bigl(r_{\rm accept}(u)-r_{\rm persist}(u)\bigr)\,du
This illustrative byte backlog applies while dirty work remains positive and rates are bytes/s, before clipping at zero. It assumes accepted and persisted byte categories are compatible; overwrites, batching, and durable-log overhead need separate accounting.↔ Scroll wide equations horizontally.

Cache-aside has a concurrent refill race

In cache-aside, a miss commonly reads the origin and later fills the cache; a writer commits to the origin and invalidates the cached key. Consider a reader that fetches old version 10 and pauses. A writer commits version 11 and deletes the key. The reader then stores version 10, resurrecting stale data after the invalidation. Delete-after-commit did not fail to execute; its ordering simply did not fence the already in-flight old fill.

A second delayed delete can reduce exposure under timing assumptions but is not a proof under arbitrary process pauses and network delays. Stronger designs can use source versions, generation-checked fills, or a source-of-truth protocol that makes stale publication fail. Any version floor or tombstone must survive long enough and in the right failure domain to reject delayed work. Strict freshness requires a stronger argument than a TTL eventually removing the stale value.

R10≺W11≺I11≺F10R_{10}\prec W_{11}\prec I_{11}\prec F_{10}
The abstract order is old-version read R 10, committed newer write W 11, invalidation I 11, then delayed old fill F 10. It is a counterexample trace, not a duration estimate. An unguarded final fill defeats the intended freshness ordering.↔ Scroll wide equations horizontally.

Failure tests distinguish patterns from promises

Exercise every boundary independently: origin commit before cache failure, cache acknowledgment before persistence failure, duplicate write replay, delayed fill, and invalidation loss. Observe the returned write result and what later reads can actually see after restart. Use idempotent source operations or operation identities where retries can repeat work, and make ambiguous outcomes explicit. Changing a pattern for performance must not silently weaken durable-write or read-after-write expectations that callers already rely on.

The queue lab illustrates a dirty-work capacity gap only. Reset and set both λ=4, μ=2, predict six queued units at t=1, then use two Steps. For a separate run Reset and re-set λ=2, μ=4, predicting two at t=1. These are fluid jobs starting at four, not persisted bytes or a write-back log. The model contains no cache-aside race, transaction, acknowledgment, or crash recovery. Use it to state why an indefinitely slower persistence path needs backpressure or a bounded failure policy.

A correctly delivered invalidation is still insufficient

A cache miss reads origin version 10 at time 0, then pauses. A writer commits version 11 at time 1 and invalidates at time 2. The old reader fills at time 3. Assume no version guard and no later writes.

  1. At time 2 the cache is absent, so the invalidation has completed its requested deletion. The writer's origin state is version 11.

  2. At time 3 the paused reader stores version 10. A later cache hit can return the old value despite the successful commit and invalidation.

  3. If the cache enforces a retained minimum source version 11 atomically, the version 10 fill is rejected. The design must also establish and preserve that floor; merely attaching a version label without checking it does not change the outcome.

The result

The race is about delayed publication. Successful delete delivery alone does not prove strict freshness under concurrent cache-aside fills.

Explore the model

Interactive lab

Interactive lab · queue

A write-back budget is not a durability proof

Reset, set λ=4, μ=2;predict backlog 6 at t=1, then two Steps. Reset and re-set λ=2, μ=4;predict 2 at t=1. The fluid job queue has no persistence log, transaction, cache invalidation, or recovery semantics.

A write-back budget is not a durability proofFluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Current readings: Fluid backlog: 4; Net rate · λ − μ: −1 /s; M/M/1 mean residence: 1 s. All parameters are adjustable with the labeled controls below.02.557.51001.534.56Elapsed time · sFluid backlogλ < μ
Fluid backlogCurrent time
Fluid backlog
4
Net rate · λ − μ
−1 /s
M/M/1 mean residence
1 s
t = 0 s

Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forAccepted work that outruns persistence needs a bounded budget and explicit acknowledgment guarantees.

Check your understanding

Why does origin-commit-then-delete fail to prove strict cache-aside freshness?

Try it yourself

A write-behind system accepts 200 KiB/s and persists 150 KiB/s for forty seconds, starting with no dirty backlog. Calculate the added dirty payload and explain what a crash promise must specify.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Integrate the positive rate difference, then separate volatile state from a recoverable record.

Compare with the solution

The excess is 50 KiB/s, accumulating 2,000 KiB, approximately 1.953 MiB, over forty seconds. If writes were acknowledged before origin persistence, the system must say whether that dirty work survives a crash and how it replays in order without harmful duplicates. A volatile cache alone cannot justify a durable acknowledgment; metadata and log overhead also exceed this payload-only estimate.

Take it with you

  • Pattern names do not establish atomicity, durability, or acknowledgment semantics.
  • Cache-aside invalidation can race delayed old fills.
  • Dirty work and guarded publication need explicit recovery and capacity rules.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.