Measuring latency and throughput
Two numbers dominate LLM serving. TTFT is how long before the first token appears, and it is governed by prefill, which is compute bound. TPS is how fast tokens arrive afterwards, governed by decode, which is memory bandwidth bound. Different phases, different bottlenecks, different fixes.
TTFT is unambiguous. TPS is not, and the ambiguity causes real confusion in benchmark comparisons, because the same three letters describe both a latency metric and a throughput metric. When precision matters, say which you mean:
- Perceived TPS is tokens per second for one user. A latency metric.
- Total TPS is tokens per second across the whole service. A throughput metric, and typically far larger.
- Inter-token latency is the gap between consecutive tokens. 10 ms of ITL is 100 tokens per second per user.
Both metrics assume streaming output and a human reading it. When the output is a tool call an agent will parse, individual tokens have no value on their own and the only number that means anything is total response time.
1.4.1Latency percentiles#
Mean latency is the most commonly reported figure and a poor summary of the distribution. Response times are right-skewed: most cluster near a mode, and a long tail stretches out to the right. The mean gets dragged toward the tail without describing it, so it simultaneously overstates the typical experience and understates the bad one.
Percentiles say something checkable instead. P90 means one request in ten is slower than this; P99 means one in a hundred. Those outliers do disproportionate damage, because a product where nine interactions feel instant and the tenth hangs for several seconds gets remembered as unreliable rather than fast.
Pushing the mean down is worth doing. Pushing P90 and P99 down is what makes a product feel dependable, and it is usually the harder and more valuable work.
1.4.2End-to-end metrics#
The last distinction is where you start and stop the clock. Inference time is on-GPU time: how long generation itself took. End-to-end time is what the user experienced, including network round trips, queueing, load balancer hops, and whatever your client code does before and after.
Keep both. Inference time tells you whether your model performance work is landing. End-to-end time tells you whether any of it reached the user.
The gap between them is diagnostic. When inference time is excellent and end-to-end time is poor, more kernel work will not help you: the problem is in the infrastructure, and Chapter 7 is where to look.