The frame: what "durable" means
Why is durability not a yes/no property, and which two numbers measure it?
Failure arrives without warning
In storage layout, every question was about cost. A bad layout is slow but not wrong. You can fix it later, because the system stays alive while you think.
Durability removes that comfort. The new constraint is a failure boundary that arrives without warning, at an instant chosen by bad luck, and may destroy any part of everything that is "in flight". It is not a slow path. It is a cut in reality: everything before the cut exists, and some arbitrary subset of what was being written does not.
What stops mattering is average throughput on the main data-page path. The central trick of this whole mechanism is to separate two moments: the moment a write becomes safe, and the moment it is put where it belongs. We make it safe quickly in a cheap way, and we move it to its final place later.
The guiding question becomes:
Recovery is the process that runs when the system restarts after a crash and rebuilds a correct state from what survived.
There is a second, harder property. Durability is the only major system property you cannot test at the moment you claim it. You can measure latency. You can check correctness by looking at output. But you can test durability only by crashing the system, which is what chaos testing does on purpose. So every mechanism here runs on every normal request, but is truly exercised only in the rare crash. Bugs, lies and wrong settings pile up silently and are discovered all at once, at the worst time. In many systems, failures are silent by default. Here it is not a tendency; it is the defining feature.
The durability ladder
"Durable" is not true or false. It is a position on a ladder. Each rung survives more kinds of failure than the one below it, and each rung is bought by a specific mechanism.
| Rung | Where the data is when you say "yes" | Survives | Still lost by | Rough cost | Bought by |
|---|---|---|---|---|---|
| 0 | Client memory | nothing | anything | 0 | nothing |
| 1 | Server memory or an unflushed log buffer | client crash, network drop | death of the server process | ~µs | asynchronous acknowledgment ("ack") |
| 2 | OS page cache (write() has returned) | the process being killed | kernel panic, power loss | ~1–5 µs | buffered write |
| 3 | Device write cache, no flush command sent | OS crash | power loss | ~10–50 µs | a "lie", usually not on purpose |
| 4 | Media, or a cache with power-loss protection, and the flush command was honoured | power loss on this machine | loss of the whole machine, media death, corruption | 20 µs (NVMe SSD, a fast flash drive on the PCIe bus, with power-loss protection) up to 10 ms (hard disk) | write-ahead log + fsync, group commit, battery-backed memory |
| 5 | Media in at least 2 independent failure domains | loss of one machine or disk | correlated failure, a logical error that was copied everywhere | +1 network round trip (0.2–1 ms in the same availability zone) | synchronous replication, quorums (a minimum number of copies that must confirm), erasure coding (storing data as chunks plus parity instead of full copies; Durability across machines) |
| 6 | At least 2 domains and a copy separated in time | DROP TABLE, a bad deploy, a software bug | corruption older than your retention window | + storage × number of copies | snapshots, point-in-time recovery, retention |
| 7 | At least 2 domains, and verified to be still readable | bit rot, silent corruption | bugs in the verifier itself | continuous read bandwidth | checksums, scrubbing |
(A failure domain is a set of things that can fail together: one disk, one machine, one rack, one datacenter, one software version, one operator.)
Two things to notice before any mechanism.
- Rungs 0–4 are about the honesty of one machine. Rungs 5–7 are about independence and verification. This is the real division of this mechanism. Logs and undo, Group commit and fsync, Bounding the log and When the storage lies mostly climb rungs 1–4 and then 7; Surviving your own mistakes is rung 6; Durability across machines is rung 5; and Durability across a pipeline asks the whole ladder again of a chain of systems.
- This mechanism is measured in two numbers that people often forget to name:
- RPO (Recovery Point Objective): how much recent work a failure is allowed to take. "RPO = 60 seconds" means that after a disaster you may lose up to the last 60 seconds of writes.
- RTO (Recovery Time Objective): how long until the service works again after a failure.
Every mechanism below buys position on one of these two numbers, and the two trade against each other through the log.
What "durable" does not promise
A durable write is kept. That is all it promises, and four neighbouring promises are often read into it:
- Not available. A record on the disk of a machine that is switched off is durable and unreachable. Durability is about RPO, what survives; availability is about RTO, when you can reach it again.
- Not correct. A wrong
UPDATEis stored with exactly the same care as a right one, and every replica copies it. Durability keeps what you wrote, not what you meant. Rung 6 exists for this, and whether the values are right at all is a different check (data quality). - Not visible. A write that is durable on a replica can still be invisible to a reader of that replica. Which histories readers may see is consistency's question.
- Not forever. Every copy has a retention period, after which it is deleted on purpose. A promise that expires is still a promise, but its length belongs in the promise (Durability across a pipeline).