Systems · 20 min

Queueing and tail latency

Why a busy server is slow long before it is full, why p99 matters more than the average, and how a token bucket keeps traffic in check.

01Why it matters

Why a server at 90% feels slow

A server takes 100 ms to handle a request and is busy 90% of the time. It still has 10% to spare, so requests should take about 100 ms, maybe a little more. In fact they take about a second on average, and the unluckiest 1 in 100 more than four and a half seconds.

The reason is that requests don't arrive politely one after another. They arrive at random, so sometimes several land at once and have to wait in line, and a busy server has little slack to work the line down. This lesson shows how a line forms, why it explodes as the load nears 100%, why the slowest requests matter more than the average, and how a rate limiter keeps a service out of that danger zone. It is the first tool of capacity planning, and of system design.

02Key parts

The pieces you will see

arrival rate λ
How many requests arrive per second, on average. They come at random moments (a Poisson process), so they bunch up.
service rate μ
How many requests one server finishes per second, on average. Its mean service time is 1/μ: μ = 10 means 100 ms.
load ρ
The share of the servers' capacity the arrivals use: ρ = λ / (c·μ) for c servers. At 1 or more the line grows forever.
latency
Waiting in line plus being served. It is what a user feels.
p50 and p99
Percentiles of latency: half the requests are faster than p50, and 1 in 100 is slower than p99, the "tail".
token bucket
A rate limiter: a bucket of tokens that refills at a steady rate. Each request spends one, and an empty bucket turns requests away.

03See it work

Watch a line form

One server, 100 ms per request on average, 8 requests a second: a load of 80%. Step through and watch the line in the top row. Each bar below is one request: the lower part is time spent waiting, the upper part time being served.

One server at 80% load. The line comes and goes in bursts, and the requests that arrive during a burst wait far longer than they are served.

A handy check on any of these numbers is Little's law: the average number of requests in the system equals the arrival rate times the average latency, L=λWL = \lambda W. At 8 requests a second and 500 ms each, 4 requests are inside on average. It holds for any queue, random or not.

04Predict

Your turn: will it wait?

The player stops before some arrivals and asks whether the request will have to wait, then asks what more traffic would do to the slowest requests. Look at the top row: is every server busy?

Make 4 predictions: step forward and answer each question before the next step plays.

0 of 4 made

05Try it

Try it: load, tails and more servers

Try the light load and the nearly full one, and compare p99 with the mean in the summary. Then try two servers sharing one line at the same 80% load: with a shared line, a server never sits idle while someone waits, so the mean drops from 500 ms (two separate lines) to about 280 ms, and p99 roughly halves.

Two servers sharing one line at 80%. Change λ, μ or c in the input box to explore.

06Try it

Protect it with a rate limit

A service can only stay out of the danger zone if traffic can't push it there. A token bucket in front of it holds up to a fixed number of tokens and refills at a steady rate. Each request spends a token; a request that finds the bucket empty is turned away straight away instead of joining a line that would take seconds. The capacity decides how big a burst gets through at once, and the refill rate caps the long run: in any tt seconds, at most capacity ++ rate ×t\times t requests.

A bucket of 4 tokens refilling at 2 a second, hit by bursts of 7. Each burst's first four get through.

07Check yourself

Check yourself

  1. Question 1 of 6

    One server takes 100 ms per request on average and gets random traffic at 8 requests a second. What is its load ρ?

    Your answer comes back in Review in a few days, so it sticks.

  2. Question 2 of 6

    Same server: what is its mean latency, waiting included?

  3. Question 3 of 6

    A service handles 200 requests a second with a mean latency of 50 ms. On average, how many requests are inside it at once?

  4. Question 4 of 6

    Your dashboard shows a mean latency of 120 ms, well under the 200 ms target. What should you check before celebrating?

  5. Question 5 of 6

    Two servers each 80% busy: one line each, or both sharing one line. Which gives lower latency?

  6. Question 6 of 6

    A full token bucket has capacity 5 and refills 1 token a second. 8 requests arrive at the same instant. How many get through?

08Explain it back

Say it in your own words

Why does a server's latency shoot up as its load approaches 100%, and why do engineers watch p99 rather than the average?

09Recap

What to remember

  • Load is ρ=λ/(cμ)\rho = \lambda / (c\mu). Random arrivals bunch up, so a line forms well before ρ=1\rho = 1.
  • For one server, mean latency is 1/(μ−λ)1/(\mu - \lambda): the service time divided by the spare capacity. It explodes near 100%.
  • Latency has a long tail. Set targets on p99, not the mean, especially when one page waits for many calls.
  • Little's law, L=λWL = \lambda W, links the number inside, the arrival rate and the latency, for any queue.
  • One shared line beats a line per server.
  • A token bucket caps the long-run rate at its refill rate and lets bursts of up to its capacity through: keep the rate well under what the service can sustain.
Back to path