A search page assembles itself from many services: one for results, one for advertisements, one for spelling, one for each of several personalisation signals, and a shard of the index for each partition of the corpus. They run in parallel, which is the right design — by the max rule of “Serial Sums, Parallel Maxes” the group costs what the slowest member costs rather than the sum. The question is what the slowest member costs.
Theorem · Fan-out amplificationLet a request issue n calls that are independent, and let each call complete within its own q-th percentile with probability p = q. Then the probability that every call is inside its percentile is pⁿ, and the probability that at least one is outside it is 1 − pⁿ.
The n at which pⁿ = ½ is the fan-out width at which the per-call q-th percentile has become the whole request’s median: half of all requests contain a call beyond it.
The proof is one line — independent events multiply — and the content is entirely in the numbers it produces.
p = 0.99
n = 1 0.99¹ = 0.990000 1.00% of requests contain a slow call
n = 10 0.99¹⁰ = 0.904382 9.56%
n = 50 0.99⁵⁰ = 0.605006 39.50%
n = 68 0.99⁶⁸ = 0.504886 49.51%
n = 69 0.99⁶⁹ = 0.499837 50.02% ← the break-even
n = 100 0.99¹⁰⁰ = 0.366032 63.40%
n = 200 0.99²⁰⁰ = 0.133980 86.60%
Read the n = 100 row slowly. Every backend is meeting its latency objective, every dashboard is green, nobody is paged — and 63.40% of requests are waiting on a call that is outside the objective. There is no failure here to find, because there is no failure. The system is doing exactly what it was specified to do.
What it takes to move the number
- a per-call p90 breaks even at n = 7
- a per-call p95 breaks even at n = 14
- a per-call p99 breaks even at n = 69
- a per-call p99.9 breaks even at n = 693
Those four rows are the whole strategy space. Reduce the fan-out, or push the per-call tail down by a factor of ten to buy a factor of ten in width, or stop requiring every answer — a request that can return with nine of ten results has changed the conjunction and is no longer in this arithmetic at all. There is also the option “Hedged Requests” takes, which is to change the per-call tail without changing the per-call service.
Example · Two hundred shards at a p99.9Push every call to a p99.9 — an expensive, real engineering achievement — and the break-even moves to n = 693. At a fan-out of 200 the probability that every call is inside its p99.9 is 0.999²⁰⁰, about 0.819, so 18% of requests still contain a slow call. That is a far better place to be than the 86.60% the same fan-out gives at a p99, and it is not zero and never will be.
Everything above assumes independence, and it is worth being precise about which direction reality departs from it. Real slowness has shared causes: a garbage-collection pause on a host that several calls land on, a saturated switch, a hot shard. Shared causes make slow calls arrive together, so fewer requests contain a slow call than 1 − pⁿ predicts — and the ones that do contain several. Independence is the assumption that spreads the damage as thinly and as widely as possible, and the real distribution is lumpier than it.
The misconception to name is the comfortable one: “each call is fast at its p99, so the request is.” The premise is about one call and the conclusion is about n of them, and the step between them is a multiplication that nobody performs because it does not look like there is anything to compute.