The Last CachebenderInterlude · Spirit
Interlude · Spirit
Interlude · Spirit · Lesson 9 of 14
Lesson Nine

The Three Writing Techniques

Technique unlocked The Three Seals write-through, write-behind, write-around

The problem

Reading was straightforward: the value is there or it is not.

Writing is harder, because now two places hold the same fact — the cache and the database — and a write must deal with both. Between the moment you update one and the moment you update the other, they disagree.

There are three strategies. They differ in when the database is written and whether the cache is written at all.

Write-through

Write-through means the cache owns the write. Your application writes to the cache, the cache writes to the database, and the call does not return until the database write has completed.

Both writes happen — but one after the other, not at the same time. The caller waits for the whole chain.

Application Cache Database write write success — only after both have been written
Nothing succeeds until both are written
Application → cache.put(key, value)
                    ↓
              cache writes to the database
                    ↓
              database confirms
                    ↓
Application ← success

Note who is doing the work: the cache talks to the database, not your application. That is what makes it through — and it is the same distinction that separates read-through from cache-aside.

Implementations differ on the order. Some write the cache first, then the database. Oracle's Coherence writes the database first and updates the cache only once that has succeeded, so that a failed database write can never leave a value sitting in the cache that the database has never seen.

Why people use it: the cache is never behind the database, because success is not reported until the database has the write. A subsequent read is correct. Reasoning about the system is simple.

The costs:

  • Writes are slower. You pay for both systems on every write.
  • You cache things nobody reads. Every write populates the cache, whether or not that item will ever be requested. On write-heavy data with few reads, you fill your cache with dead weight and evict things people actually want.
  • It is not actually atomic. Writing to two systems without a transaction spanning both means one can succeed and the other fail. If the cache write succeeds and the database write fails, your cache now holds a value that does not exist in the source of truth — which is worse than being stale.

Where you would use it

  • Account and profile settings. Someone changes their display name and lands straight back on a page showing it. The cache is already correct when that page renders.
  • Feature flags and configuration. Written rarely, read on nearly every request, and every server needs the new value at once.
  • Stock counts on a low-volume catalogue. Being wrong means overselling, and the write rate is low enough that the extra latency does not matter.
  • Shopping cart contents. Written, then immediately read on the next page, every time.

The pattern: read-after-write is common, and being wrong is worse than being slow.

Write-behind

Write-behind — also called write-back — writes to the cache, returns success immediately, and writes to the database later in the background.

Application Cache Database write success, now later lost if the cache dies first
Success is reported before the database is written
Application → write to cache → return success   ← user is done here
                             ↓
                    (later) write to database

Why people use it:

  • Writes are very fast. The user waits for a memory write, not a disk write.
  • Writes can be batched. A counter updated 1,000 times in a second becomes one database write of the final value. For write-heavy workloads this is a genuine order-of-magnitude reduction in database load.
  • Sudden write spikes get absorbed instead of overwhelming the database.

The cost, stated plainly: you can lose data.

If the cache dies between the acknowledgement and the database write, that write is gone. You told the user it succeeded. It did not.

This is not a rare edge case to design around — it is the fundamental trade. Write-behind is correct for data where losing some is acceptable. It is wrong for orders, payments, and inventory.

Where you would use it

  • View counts. A page viewed a million times an hour becomes a handful of database writes instead of a million.
  • “Last seen” and “last active” timestamps. Updated on every single request, and nobody notices if one is a minute stale or lost entirely.
  • Likes, reactions, and vote tallies. High volume, and an occasional lost increment is invisible.
  • Analytics and telemetry events. Losing a fraction of a percent does not change any dashboard anyone looks at.

The pattern: enormous write volume, and nobody files a support ticket if a few writes vanish.

The test to apply: if thirty seconds of these writes disappeared in a crash, would anyone notice? If the answer is yes, this is not your strategy.

Write-behind is not a faster write-through. It is a different guarantee. Write-through promises durability. Write-behind promises speed, and explicitly does not promise durability.

Write-around

Write-around writes only to the database and does not populate the cache at all. Usually it also removes any existing cached copy, so a stale one cannot survive.

Application Cache Database write delete the copy the next read misses, and reloads it
Write to the database, then remove any cached copy.
Application → write to database → return success
              (cache entry deleted if present)
              next read misses and loads fresh

Why people use it: write-heavy data that is rarely read soon after writing does not pollute the cache. Your cache stays full of things people are actually reading.

The cost: the next read of that item is a miss. If your write pattern is “write then immediately read” — which is extremely common, since users usually look at what they just did — write-around gives you a guaranteed miss on every one.

Where you would use it

  • Bulk imports and migrations. Loading a million rows overnight. Filling the cache with all of them would evict everything real users actually want — the exact scan problem you will meet in Lesson 10.
  • Audit logs and event records. Written constantly, read almost never, and usually only during an investigation.
  • Historical and archival data. An order from three years ago is written once and may never be read again.
  • Draft autosave. A user saves every few seconds; only the final version is ever read by anybody else.
  • Sensor and IoT readings. High write volume, queried later in aggregate rather than individually.

The pattern: written far more often than read, or not read again for a long time.

Choosing

Situation Strategy Because
Read soon after write, must be correct Write-through Cache is right immediately
Very high write rate, some loss acceptable Write-behind Speed and batching
Written often, read rarely Write-around Keeps the cache useful
Read-heavy, occasionally written Write-around + cache-aside Simple, safe, and the common default

That last row deserves attention. Write-around paired with cache-aside — write to the database, delete the cached copy, let the next read reload it — is the most widely used combination in practice, because it is simple and it fails safely. It is also, under a different name, the subject of Lesson 11.

At the Storefront

Stock count — decrements constantly, and being wrong means selling something you do not have. Write-through keeps the cache from showing more stock than exists, but note that a write strategy alone does not make a decrement safe: two servers can both read 5, both subtract 1, and both write 4. That is the read-modify-write race from Lesson 6, and it needs an atomic decrement rather than a write pattern. Not caching the stock count at all is a legitimate answer here.

Review submission — written rarely, read constantly. Write-around: store it, drop the cached review list, let the next reader rebuild it.

Product view counter — written on every page view, read almost never, and losing a few is fine. Write-behind, batched.

Three write paths, three different strategies, on one page.

Common misconception

“Write-behind is just a faster write-through.”

It trades durability for speed. If the cache dies before the flush, the write is gone — after you told the user it succeeded. Choose it deliberately, for data you can afford to lose.