9 lessons

Latency, Throughput & Queueing

The physics of a loaded system: tail latency, latency budgets, Little's Law as working intuition, why queueing makes systems slow long before they fail, and what saturation actually means.

SymptomSignalMeasurementHypothesisEvidenceRoot CauseChangeValidationRegression Check

Every lesson below starts from an observable symptom and ends with the measurement that proves the fix worked. Numbers carry a label saying whether they were measured, estimated, simulated or invented to show a shape.

Latency Is a Distribution, Not a Number

The dashboard says 120 ms and users say it is slow. Both are right: "the latency" was never one number. Response time decomposes into service time and wait time, and almost every production surprise lives in the waiting.

Symptom · Support tickets say the app is slow. The service dashboard shows average latency flat at 120 ms and nobody can reproduce the complaint.
Tail Latency: Why p50 Being Fine Does Not Help

A one-in-a-hundred slow response sounds harmless until a page makes 40 calls, a user makes 30 page views, and every dependency has its own one-in-a-hundred. Rare events compose, and at scale the tail becomes the typical experience.

Symptom · p50 is 40 ms and stable. Users describe the product as "randomly slow", and the complaints do not correlate with any single endpoint or customer.
Latency Budgets: Spending 200 Milliseconds on Purpose
▶ lab

A latency target is only useful once it is divided. Give every hop an allowance, add them up, and the conversation changes from "make it faster" to "the payment provider is spending 45% of our budget and we have 15 ms left".

Symptom · The team agreed on a 200 ms target months ago. Nobody can say whether any individual service is within budget, so every latency conversation ends in "we should all be faster".
Throughput: The Number That Means Nothing Without a Latency Bound

"We handle 10,000 requests per second" is not a capability claim until you say at what latency and with what error rate. Push a system to its maximum throughput and you will find the maximum is a place nobody wants to operate.

Symptom · A capacity test reports the service peaks at 10,000 rps. In production the same service becomes unusable at 6,000 rps, and nobody can reconcile the two numbers.
Little's Law as Working Intuition
▶ lab

Concurrency equals throughput times latency. Three lines of arithmetic size a connection pool, expose an impossible capacity claim, and turn a queue depth into a wait time — which is most of what the law is for.

Symptom · Someone proposes a pool size, a thread count or a capacity number and nobody can say whether it is roughly right. The numbers are chosen by copying another service or by doubling until the errors stop.
Queueing: Why Systems Get Slow Before They Get Broken
▶ lab

Load rises 20% and latency rises 400%. Nothing errored, no code changed, no dependency degraded. A queue formed — and queues turn a linear increase in arrivals into a non-linear increase in waiting.

Symptom · Traffic grew from 4,000 to 5,000 requests per second over a week. p99 went from 180 ms to 2.4 seconds. Error rate is still near zero and every dashboard shows resources "not fully utilized".
Saturation: The Reading Utilization Cannot Give You

Utilization says how busy a resource was. Saturation says how much work could not be served immediately. A CPU at 55% with twelve threads waiting for eight cores is not half idle — it is oversubscribed, and only one of those two numbers says so.

Symptom · Latency is bad. CPU is at 55%, memory is at 60%, disk is at 40%, network is at 20%. Every resource chart looks fine and the team concludes it must be the application code.
Concurrency Limits: An Unbounded Server Is a Slower Server

Accepting every request that arrives feels generous and produces the worst possible outcome: everything is slow, everything times out, and the capacity is spent on work nobody is still waiting for. A limit is a latency control, not just a safety valve.

Symptom · Under a traffic spike the service does not reject anything, but every request takes 30 seconds and nearly all of them time out. Throughput measured in *useful* responses drops close to zero.
Timeouts: The Latency Contract Nobody Writes Down

A timeout is a statement about how long a caller will wait before deciding the answer is worthless. Set it too short and you manufacture load; too long and you tie up capacity waiting for work that stopped mattering minutes ago.

Symptom · A dependency slows from 200 ms to 3 s. The service does not merely slow down: its error rate goes to 40%, its own upstream starts timing out, and load on the already-struggling dependency triples.