A logarithmic axis, because a linear one would draw everything below a disk seek as a flat line on the floor. Each gridline is a factor of a thousand — the ladder covers nearly nine orders of magnitude from a CPU cycle to Amsterdam.
The ladder ranks latency — the cost of asking. Once you ask for enough at once, you are paying for the transfer instead, and the ranking collapses. Drag the slider and watch three media that differ by a factor of five hundred at 4 KB end up within a factor of twenty.
The rule is usually stated as three numbers: RAM around 100 ns, an SSD around 100 µs, a spinning disk around 10 ms, each rung roughly a hundred times slower than the last. Two of those numbers are fine. The word “each” is not.
100 ns to 100 µs is a factor of a thousand. 100 µs to 10 ms is a factor of a hundred. So the ladder the mnemonic names goes up by 1000 and then by 100, and calling both of them “×100” understates the first gap by an order of magnitude — which is the gap that matters most, because it is the one between the thing your program does constantly and the thing it should be avoiding.
The useful version of the rule is not a constant. It is: memory to disk is 100,000×, and everything in systems design follows from that one number. Five orders of magnitude is why caches exist, why a database index is worth the write cost, and why an unexpected disk read in a hot loop does not slow a program down — it stops it.
Take one nanosecond and call it one second. Every figure on this page multiplies by the same billion, so every ratio survives exactly — and the ladder turns into something a person can hold:
A cache hit is one second. A memory read becomes 100.0 seconds — under two minutes, a pause. A SATA SSD read becomes 41.7 hours: you asked a question on Monday morning and got the answer on Tuesday night. A disk seek becomes 3.8 months. And a packet to Amsterdam and back becomes 4.8 years — you would have started a degree.
That is the whole content of the rule, in a form nobody argues with. The reason a network call inside a loop is a different kind of mistake from a slow function is not that it is slower. It is that it is a different unit of time, and the loop was written by someone thinking in seconds.
The Rulebook entry notes that a spinning disk streaming sequentially can beat an SSD serving random 4 KB reads — and against a SATA SSD it comfortably does, by about seven times. Against a modern NVMe drive it no longer does: 4 KB random reads land at roughly 205 MB/s against a disk’s 200 MB/s of streaming, which is a tie rather than a win. The example was true when it was written and is now a period piece, which is a fair description of most performance advice.
No, and the rung it gets wrong is the one that matters. RAM at 100 ns to an SSD at 100 µs is a factor of a thousand; the SSD to a spinning disk at 10 ms is a hundred. The version worth remembering is that memory to disk is 100,000×, and most of systems design follows from that one number.
Because nobody has intuition for a nanosecond. Call one nanosecond one second and every ratio survives exactly: a memory read becomes 100 seconds, a SATA SSD read 41.7 hours, a disk seek 3.8 months, and a round trip to Amsterdam 4.8 years. A network call inside a loop is not slower; it is a different unit of time.
Streaming sequentially against a SATA SSD serving random 4 KB reads, comfortably — by about seven times. Against a modern NVMe drive it no longer does: random reads land near 205 MB/s against a disk’s 200 of streaming, which is a tie. The classic counterexample was true when written and is now a period piece.
That a small tail becomes a large one when a request touches many services. If each of n calls has probability p of being slow, the chance the whole request is slow is 1 − (1 − p)n, and at a hundred calls even a 1% tail affects most requests.
Nobody opens a latency ladder to look up one number. They open it holding a request in their head — a cache check, a database read, a call to another service — and wanting to know where the time goes. Add the steps and find out. The answer is almost always that one of them is the whole budget and the rest are rounding.
A request that asks one backend takes about as long as that backend usually takes. A request that asks a hundred of them in parallel and waits for all the answers does not: it takes as long as the slowest of the hundred. So the rare slow response stops being rare from the caller's point of view, and it does so much faster than anyone expects.
If each backend independently has a chance p of being slow, the chance that none of n of them is slow is (1 − p)n, and everything else is one minus that. With a one-in-a-hundred chance and a hundred backends, the chance of a clean request is 0.99100 — about 37%. Nearly two requests in three meet a slow backend, from a component that is well behaved 99 times out of 100.
Which is why tail latency is a system property, not a component property. Tuning a backend from 99% to 99.9% well-behaved takes the same fan-out from 63% affected to 10% — an enormous change in the user's experience from a component improvement most dashboards would not even show. And it is why the standard answers are structural rather than about speed: ask fewer backends, hedge the request by sending a duplicate to a second replica once the first is late, or return a partial answer rather than waiting for the straggler.
A search page fans out to 50 shards. Each responds in 5 ms typically, and spends 2% of its responses in a 100 ms tail — garbage collection, a cold cache, a noisy neighbour.
A single shard therefore looks excellent: 98% of the time it answers in 5 ms. But the page waits for all fifty, and the chance that all fifty are quick is 0.9850 — just 36%. So 64% of page loads take 100 ms, not 5. The median user experiences the tail.
Halving the shard count to 25 takes that to 40%. Fixing the shards so only 0.2% of responses are slow takes it to 10%. Sending a hedged request to a second replica after 10 ms makes a slow shard need both replicas to be slow at once, which at 2% each is 0.04% — and the fan-out barely notices it at all. That last one costs a few per cent more load and is usually the cheapest of the three.
Every figure here is an order of magnitude and your hardware will differ. What does not differ is that memory is about a hundred thousand times quicker to reach than a spinning disk: a ratio that has survived every generation of both, because they are limited by different physics.
On the human clock a memory read is a pause and a trip across an ocean is nearly five years. That is why a remote call inside a loop is a different category of mistake from a slow function: nothing about the surrounding code was written expecting it.
Memory to SSD is a thousandfold, not a hundredfold. The rule claims the tiers are orders of magnitude apart, not a constant factor apart, and the first gap is the one it understates.
Once you ask for a few megabytes at once you are paying for the transfer, not the access, and three media that differ by five hundred times at 4 KB come within twenty times of each other. Most real workloads sit in between, which is why benchmarks disagree so violently.
A drive serving thirty-two requests at once behaves nothing like one serving them one at a time. This page models a single request in flight, the pessimistic case and the one the ladder is usually quoted for.
Nothing here models a cache, and every real system is mostly cache hits. The ladder describes what happens on the reads that miss, which is why one extra miss per iteration is so expensive.
This page has changed in 139 archived releases, but each of those was a site-wide pass, so none is attributable to this tool on its own and none is listed here. That is not a claim that the tool never changed — a release that reworked many pages at once may well have altered this one too. The changelog has them.