Patterns

Write-through and write-behind

Let the cache take writes too, either passing each one straight on to the database or holding it briefly, so reads never see an old value.

A write-through cache writes to the database before it answers, and a write-behind cache answers first and writes later.

Use it when#

  • Cache-aside leaves users reading old rows right after a write, and you can see it in stale-read reports.

  • Writes to the same few keys arrive in bursts, so batching them would save database work (write-behind).

  • The data tolerates a short loss window if the cache dies (write-behind only).

How it works#

With write-through, the app writes to the cache, the cache writes to the database, and only then does the call return. The cache never disagrees with the database, so reads need no invalidation. With write-behind, the cache acknowledges at once and flushes batches to the database on a timer. A counter bumped 100 times in a second can reach the database as one update.

writethrough: waitbehind: later, batchedAppCacheDatabase

What it costs#

Write-through adds the cache's write time to every write and fills the cache with keys nobody reads. Write-behind is faster and cheaper on the database, but a crash loses whatever was not flushed yet, and the database lags the cache in the meantime. Use it for counters and likes, never for payments.

In Quorum#

The Cache has a Cache strategy option, and picking anything but cache-aside needs Cache strategies. The two Designs below differ from cache-aside only in the strategy, so their captions show what it changes.

Drag to pan. Hold Ctrl or Cmd and scroll to zoom.

At 1.50k Users the Simulation solves this Design to Apdex 1.00, p99 211 ms, 0.0% errors and $1.28/s Burn.
WhereSettingValueWhy
App ServerInstance sizesmallSmall gives the app two vCPUs, enough to run code while the data tier does its own work.
CacheCache strategywrite-throughEach write goes into the Cache and on to the Database before it returns, so the Cache never holds an old value.
CacheTTL (seconds)60The TTL only bounds how long a rarely written key stays in memory, since writes keep the entry fresh.
CacheInstance sizesmallMemory decides how much of the hot set fits. A Cache too small for it misses even on popular rows.
DatabaseInstance sizesmallSmall gives the Database two vCPUs, so the figures below reflect the Cache and not a starved Database.

Research this Design needs: Caching, Cache strategies.

Drag to pan. Hold Ctrl or Cmd and scroll to zoom.

At 1.50k Users the Simulation solves this Design to Apdex 1.00, p99 192 ms, 0.0% errors and $1.28/s Burn.
WhereSettingValueWhy
App ServerInstance sizesmallSmall gives the app two vCPUs, enough to run code while the data tier does its own work.
CacheCache strategywrite-behindThe Cache answers a write at once and flushes to the Database later, in batches, so the Database sees fewer writes. A Cache crash loses what it has not flushed.
CacheTTL (seconds)60Reads still expire on this clock, but a write lands in the Cache first, so a key stays current while it is written often.
CacheInstance sizesmallMemory decides how much of the hot set fits. A Cache too small for it misses even on popular rows.
DatabaseInstance sizesmallSmall gives the Database two vCPUs, so the figures below reflect the Cache and not a starved Database.

Research this Design needs: Caching, Cache strategies.

The Stale reads incident shows why the strategy matters. The glossary defines write-through cache.