Interlude · Spirit
The Three Writing Techniques
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.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 → 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-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 → 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.
“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.