Definition · Durable write, fsync, group commitA write is durable when it survives the loss of power. fsync is the call that forces buffered bytes onto the device and returns when they are there; t_fsync is how long it takes. Group commit is the practice of batching B pending commits behind a single fsync and acknowledging them together.
The durable write rate is at most 1/t_fsync without grouping and B/t_fsync with it. Both are ceilings, not achieved rates.
The misconception this lesson is aimed at is that a successful write() means the data is safe. It means the bytes reached the page cache, which is memory, which is exactly the thing a power loss empties. Every engine that promises durability is therefore paying for fsyncs, and the count of them is the whole budget.
t_fsync = 10 ms = 0.01 s arrivals λ = 5 000 a second
B = 1 cap 1/0.01 = 100 durable writes a second
batches arrive at 5 000/s, served at 100/s → ρ = 50
no steady state: the backlog grows without bound
B = 64 cap 64/0.01 = 6 400 durable writes a second
fsync per write 0.01/64 = 156.3 µs
fill wait (64 − 1)/(2 × 5 000)= 6.30 ms
batches 5 000/64 = 78.125/s against 100/s → ρ = 0.781
queue + fsync 1/(100 − 78.125)= 45.71 ms
commit latency 6.30 + 45.71 = 52.01 ms
The B = 1 row is worth reading twice. At five thousand writes a second arriving and one hundred fsyncs a second available, the utilisation is 50 and there is no mean latency to quote at all — the backlog simply grows. The ceiling arrives as a queueing fact rather than as an assertion, which is the M/M/1 model of Queues and Utilisation reused rather than a second model invented here.
What the batch costs
Two waits, moving in opposite directions. The fill wait is how long a write sits while its batch assembles, about (B − 1)/2λ on average, and it grows linearly in B. The queue in front of the fsync shrinks as B grows, because batches arrive at λ/B while the fsync still serves at 1/t_fsync, so the utilisation ρ = λ t_fsync/B falls. Adding the two gives a curve with an interior minimum.
Example · Scanning the curveAt λ = 5 000 and t_fsync = 10 ms: B = 64 gives 6.30 ms of fill and 45.71 ms of queue, 52.01 ms in total. B = 121 gives 12.00 ms and 17.04 ms, 29.04 ms in total — the lowest on the curve. B = 256 gives 25.50 ms and 12.43 ms, 37.93 ms, and is past the minimum: the batch is now the problem. The durable ceiling rose the whole way, from 6 400 to 25 600 a second, while the latency turned around.
The lab finds that minimum by evaluating every B rather than by a formula, and it says so. A closed form exists for this shape of bargain — a fixed cost amortised over a batch against a cost that grows with the batch — and it belongs to “The EOQ Formula Without Calculus” on the Operations Research path. The same trade appears again as “Batching: Cost and Latency” in Scaling Laws and Cost, with throughput in place of durability and a per-item cost in place of a holding cost.
Two things this model takes on trust, both of which have cost people data. It assumes t_fsync is what the device actually does, and a device with a volatile write cache that acknowledges an fsync before the platter has it will report a delightful figure and lose your commits anyway — measure it, do not read it off a datasheet. And it assumes a single thread issuing the fsyncs, which is what makes the M/M/1 arithmetic apply.