Model intelligence

LLM latency benchmarking: TTFT, throughput, and the long tail

Measure first content, full completion, quality, and failures without hiding the conditions behind the numbers.

HFAPI.com illustrated cover: MEASURE WHAT MATTERS.

A language model can begin answering quickly and still take a long time to finish. Another can generate tokens rapidly once it starts but spend most of its response time waiting for capacity. Calling both systems “fast” hides the difference that matters to an application. A useful LLM latency benchmark separates the stages of a request and describes the workload that produced them.

The objective of this guide is a reproducible evaluation, not a leaderboard. It offers a measurement plan you can adapt to a chosen model, hosting route, and task. HFAPI.com does not publish invented provider rankings or imply that an illustrative test represents a service guarantee.

Define the experience you are measuring

Begin with the consuming workflow. A chat interface may care strongly about the delay before readable content appears. A structured extraction pipeline may care only about the time until the entire validated object is available. An offline job may prioritize accepted outputs per unit of cost. These are different objectives, so they should not share an unexplained single performance score.

Write a success rule before running the test. Include quality, completeness, and the deadline as well as network success. If the output must contain a valid category and a supporting passage, a fast but invalid answer is a failure. Describe what the user actually waits for. This prevents a benchmark from measuring a convenient internal event while overlooking the last stages that make the result useful.

Put timestamps at meaningful boundaries

Record request initiation, first response headers, first content-bearing output, final output, and completed validation where your client can observe them. These timestamps represent different milestones. A connection opening or an initial metadata event is not necessarily the first useful token. Use a monotonic clock for durations measured within one process so wall-clock adjustments do not distort elapsed time.

Client-side measurement

The vLLM production metrics documentation identifies separate metrics for first-token latency, inter-token latency, request queue time, and end-to-end request latency. That separation is useful when instrumenting a compatible serving stack. Client-side observations still include parts of the journey that a server metric may exclude. Label your measurement boundary explicitly rather than combining client and server timings as though they were directly interchangeable.

Control the input and output distributions

A model handling a short question is not doing the same amount of work as one processing a long document. Construct prompt buckets that resemble the real workload: short, typical, and long inputs, with representative output requirements. Record the tokenizer or counting method when reporting token lengths. Comparisons based only on character count can conceal differences in how models represent the same text.

Set output limits consistently and retain the actual output length for each request. A system that stops early may appear faster while delivering incomplete work. Keep generation settings and prompt templates in the test manifest. Make sure that a comparison is not accidentally rewarding a model for answering with fewer required details. The model selection guide provides a complementary process for evaluating task quality alongside these performance measurements.

Distinguish cold and warm conditions

Write down what “cold” means in your test. It might describe a newly started worker, an empty application cache, a model not yet loaded, or a new network connection. These conditions have different mechanisms and should not be collapsed into a single unexplained label. State which resources were reset and which remained available before a run.

Measure startup-sensitive and steady-state behavior separately. For warm measurements, use a documented preparation procedure rather than discarding an arbitrary number of inconvenient results. For cold measurements, repeat the startup condition enough times to understand variability. Do not report the best warm result as representative of a route that frequently starts from idle. The deployment guide discusses why capacity policy belongs in a performance decision as well as a cost decision.

Sweep concurrency without hiding arrival behavior

Begin with a single outstanding request, then increase concurrency in controlled steps. Record offered load, completed requests, failures, and timeouts at every step. A benchmark client that waits for a response before sending more work naturally slows down when the system slows down. That behavior can be useful, but it does not reproduce an independent stream of incoming users.

For an arrival-driven test, record the intended request schedule and any delay introduced by the load generator itself. Verify that the client machine has enough capacity to produce the planned traffic. Otherwise the benchmark may measure its own bottleneck. Use traffic only within your authorization and account limits. Stop a run when it threatens budgets or service stability rather than treating an uncontrolled stress event as a necessary part of scientific rigor.

Keep failures in the report

A latency chart that silently excludes timeouts can make an overloaded system look healthy. Report successful latency distributions together with the number of attempts, rejected calls, partial streams, timeouts, and invalid outputs. State which categories are excluded from a percentile calculation and why. A completed-request percentile is informative, but it must not be mistaken for a summary of every attempt.

Retain enough information to distinguish a provider error from local cancellation or parser rejection. Count retries separately while preserving their association with the original task. For application-level evaluation, measure the total elapsed time and total usage across all attempts required to produce an accepted answer. This exposes systems that appear inexpensive or responsive per call but need repeated calls to satisfy the actual task.

Calculate percentiles with context

A high percentile needs an adequate sample and an explanation of the measurement method. Do not present a p99 from a tiny experiment as a stable characterization of rare behavior. Preserve the sample count, run duration, and input mix next to the number. Where possible, repeat runs at different times to see whether the result depends strongly on shared capacity or network conditions.

Avoid averaging percentiles from separate runs and calling the result the percentile of the combined workload. Retain raw observations or a suitable mergeable representation instead. Examine distributions by workload bucket before pooling them. A change in the proportion of long prompts can move the overall tail without any change in individual bucket performance. The benchmark checklist includes a downloadable manifest for recording the variables that make these comparisons interpretable.

Translate measurements into an operating decision

Suppose one route meets the first-content objective but misses the completed-object deadline. The right response might be a shorter output schema, a smaller suitable model, or a different task boundary rather than more client-side concurrency. Similarly, rising queue time suggests a different investigation from consistently slow generation after admission. Diagnose the stage responsible for the user-visible delay.

Compare cost per accepted task, not only the price of a token or the cost of a successful network call. Include retries, validation failures, and idle infrastructure where those costs apply. Preserve quality requirements while evaluating a faster option. A degraded answer is not a performance improvement unless the product explicitly accepts that tradeoff. Write the decision and its conditions so another engineer can reproduce it after the next model or deployment change.

Conclusion: publish conditions, not just numbers

A defensible LLM benchmark describes the task, inputs, outputs, hosting route, measurement boundaries, traffic pattern, and failures. It separates responsiveness from completion and keeps quality in the definition of success. The useful result is a decision about a workload, not a universal claim that one model is fastest.

Start with a modest experiment, inspect the raw observations, and expand only after the instrumentation is trustworthy. Continue through the high frequency LLM hub for caching and batching considerations. Repeat the benchmark when a meaningful configuration changes; a measurement is evidence about the tested conditions, not a permanent property of an API name.

CONTINUE EXPLORING
Back to the journal ↗

Found something that needs a closer look? Send a correction. Read our editorial standards.

KEEP YOUR CURIOSITY RUNNING

Go a little
deeper.

All field notes