workshop private

← all creations

Tail

viz · created 2026-09-07

One request fanned out to a hundred services, drawn on a log axis with the distribution it lands in directly underneath — ninety-nine leaves inside 8 ms, one at 300, and the parent waiting for that one. Hedge it or drop it and watch the same picture collapse.

architecturesimulationcanvas

A parent request asks a hundred leaf services in parallel and cannot answer until the slowest of them has. That single word — slowest — is the whole piece. The parent’s latency is the maximum of a hundred draws, and the maximum of many draws lives out in the tail whether or not the typical draw does.

The top panel is one request: every leaf plotted where it landed on a logarithmic millisecond axis. The shape is always the same. A dense teal cluster around 4 ms, then nothing, then one lonely dot far to the right with a red line through it, because that is the one the parent is waiting for. Turn the speed down and a sweep line crosses the axis so you can watch 99 leaves come back and then sit there, waiting, for the hundredth.

Directly underneath, on the same ruler, are the two distributions the run has accumulated: teal for the leaves, amber for their parents. The red line from the request above carries on down into the amber pile it is a sample of. Two things about that picture are worth the whole build:

The amber pile is somewhere the teal one is not. Leaf p99 sits around 12 ms. Parent p99 sits around 310 ms — twenty-six times further out, from a service nobody changed. Every number on the leaf’s dashboard is still green.

The amber pile has two humps. One at 11 ms, where the tail happened to miss all hundred leaves; one spread across 50–500 ms, where it hit at least one. There is no middle. A fanned-out request does not degrade gradually, it either escapes or it doesn’t, and the ratio between the humps is just 0.995^100.

The arithmetic underneath

If a leaf answers within t with probability F(t), then n independent leaves all answer within t with probability F(t)^n. So the parent’s q-th percentile is the leaf’s q^(1/n)-th, and the bottom strip draws exactly that against fan-out, with the leaf’s own percentiles as flat lines that never move.

Set q = 0.5 and the leaf percentile hits 0.99 at n = 69. At a fan-out of 69 the median parent request waits as long as the slowest 1% of leaf requests. Nothing about the service appears in that sentence — it is a fact about maxima, and it is marked on the axis. Switch profiles and watch the crossing dot stay put while everything around it moves.

At the default fan-out of 100, the parent’s median is the leaf’s 99.31st percentile and the parent’s p99 is the leaf’s 99.99th — a percentile no dashboard graphs and no alert fires on.

The two fixes

Both come from Dean & Barroso’s The Tail at Scale, and both are in the fix dropdown so the effect lands on the picture you were already looking at.

Hedge after leaf p95. Once a leaf has been outstanding longer than its own 95th percentile, send a duplicate to another replica and take whichever answers first. Because the duplicate goes out at the threshold rather than at time zero, it costs about 5% extra load — and parent p99 drops from ~305 ms to ~18 ms. On the GC pause profile it drops from 816 ms to 11 ms. In the arena, hedged leaves draw a hollow ring where the abandoned attempt was going to land and a line back to where the retry actually did; the ring is often three decades to the right of the dot.

Answer without the slowest 1% or 5%. Stop waiting once 99 of 100 leaves are in. Same collapse, paid for in completeness instead of load — and the two options apart make the interesting point. Dropping 1% takes parent p99 from 305 ms to 143 ms; dropping 5% takes it to 10 ms. Waiting for 99 of 100 still means waiting for a second straggler whenever there is one, and the runs with two slow leaves are exactly the runs p99 is measuring.

The control that matters most

The tight · no tail profile. Same fan-out of 100, same everything, and parent p99 comes out at 10 ms against a leaf p99 of 7 ms. Not 26× — about 1.4×. Fan-out is not what costs you. The tail is what costs you, and fan-out is only the thing that reliably finds it, which is why both fixes above aim at stragglers rather than at the fan.

Reuse

src/tail.js is a framework-free ES module:

No rendering or timers in the module; the canvas demo is reference code.

Gotchas