Latency Metrics for Token Generation
The two measures that matter most for token generation are the efficiency of the compute your workload really uses, and the delay a user perceives between tokens.
A Faster Chip Is Not Automatically a Faster Service
What do you think happens?
If chip A advertises a higher peak FLOP/s number than chip B, will a model running on chip A always serve requests faster?
Reveal answer
No. A higher peak FLOP/s number does not guarantee faster serving.
FLOP/s counts floating-point operations per second, so the assumption feels reasonable. But the peak number describes what the chip can do under chosen conditions, not what your workload actually uses. Inference optimization is largely about finding where that assumption breaks down and what to measure instead.
When people compare hardware for language models, the first number they look at is usually peak FLOP/s, the maximum floating-point operations a chip can perform each second. The reasoning seems sound: more operations per second should mean more speed. This lesson shows why that reasoning fails for serving, and what to measure instead. The two measures that matter most for token generation are the efficiency of the compute your workload really uses, and the delay a user perceives between tokens.
Measuring Real Compute Use with MFU
Model FLOPS Utilization (MFU) is a measure of how efficiently a model uses the FLOPS available on a chip. It compares the work a model actually accomplishes against the capacity the hardware could deliver. The term was introduced in the PaLM paper by Chowdhery et al. in 2022, although tracking FLOP/s utilization is older than that term.
The formula makes the key point visible. A chip with a huge peak number can still produce low MFU if the workload cannot keep that hardware busy. The peak number belongs to the chip under chosen conditions. MFU belongs to your model running your workload. Two systems on the same chip can therefore show very different MFU values.
Computing MFU for a serving workload
A chip has a peak of 200 TFLOP/s. A serving workload, measured over a period, actually achieves 50 TFLOP/s of useful computation. What is the MFU?
- 1Identify the achieved work rate
The workload achieves 50 TFLOP/s, so that is the numerator.
- 2Identify the peak capacity
The chip can deliver 200 TFLOP/s at peak, so that is the denominator.
- 3Divide and convert to a percentage
50 divided by 200 is 0.25, which is 25 percent MFU.
The MFU is 25 percent. The chip is capable of four times the work the workload is actually doing, so a bigger peak number alone would not speed up this service.
Why Matmul and Data Movement Set the MFU
Most of the arithmetic in a neural network is matrix multiplication, usually called matmul. Estimates cited in the source put matmul at more than 90 percent of all floating-point operations in a neural network. That is why optimization work tends to focus on how well matmul uses the hardware. If matmul runs efficiently, MFU is high. If matmul stalls on data movement, MFU drops even when the chip is powerful.
Hardware and model design also shape each other. A chip can be built to run one architecture well, and an architecture can be designed to make the most of a chip. The transformer, for example, was originally designed by Google to run fast on TPUs and was only later optimized for GPUs. Memory technology matters too: lower-end and mid-range GPUs may use GDDR (Graphics Double Data Rate) memory, which affects how quickly data can reach the compute units.
Latency Metrics: TBT and ITL
Token generation latency is measured with two related metrics. Time between tokens (TBT) is the name used by LinkedIn, and inter-token latency (ITL) is the name used by NVIDIA. Both describe the delay between consecutive generated tokens, which is what a user perceives as the model typing. When you compare reported numbers, check which metric a team means.
Not every delay has the same effect. An experiment by Anyscale showed that 100 input tokens have roughly the same impact on overall latency as a single output token. A long prompt is therefore not free just because it produces little output. User expectations also shift over time: in the early days of chatbots, some people complained that responses came too fast and seemed unnatural, but as people became familiar with chatbots, that stopped being the case.
Splitting Online and Batch Inference
Batching for inference starts with a service decision: split the inference API into an online path and a batch path. Online requests are the ones where latency matters most, such as a user waiting on a response. Batch requests are less urgent and can be sent to a batch API and processed without the same immediacy. Separating the two lets the service focus its capacity on online requests first, so a large batch job does not delay a person waiting at a chat window.
| Property | Online inference | Batch inference |
|---|---|---|
| Urgency | High, a user is waiting | Lower, can be deferred |
| Main goal | Keep token-to-token delay low | Process work without immediacy |
| Capacity priority | Served first | Handled without delaying online traffic |
How a service treats the two kinds of inference traffic
Prefilling and the KV Cache
Caching in inference means saving work that would otherwise be repeated. For transformer models, prefilling populates the initial KV cache, which stores the key and value data the model computes for tokens it has already processed. Prefilling fills this cache before generation proceeds, so later steps can reuse the stored work instead of recomputing it from scratch.
The reason prefilling pays off is that the system prompt of an application is usually known in advance. Developers write it once and it repeats across many requests. The exact user queries are the hard-to-predict part. The stable portion of each request can therefore be processed ahead of time and kept in the cache, while only the unpredictable portion is handled fresh for each request.
Read the diagram left to right. The system prompt tokens sit in the cache with their stored key and value data, so a later request that begins with the same system prompt does not need that work repeated. Only the user query tokens, the unpredictable part, are computed fresh. The stored state is reused during the decode phase, which is how earlier tokens avoid being recomputed.
Prompt Caching and the Limits of Whole-Prompt Reuse
Prompt caching applies the same idea at the level of prompts: if a prompt has been processed before, store the result and reuse it rather than recompute it. Implementations vary a great deal, so confirm whether a given system caches whole prompts, prefixes, or only earlier messages in a session. One example from the source is llama.cpp, which has prompt caching but appears to cache only whole prompts, and only for queries within the same chat session. Caching whole prompts means a new prompt that merely shares a prefix with an old one may not benefit.
Speculative Decoding and Its Limits
Token generation is bandwidth-heavy. Each generation step requires transferring the entire model's parameters from the accelerator's high-bandwidth memory to its compute units. Because the model produces only one token at a time, that step uses only a small number of FLOP/s, which is a form of computational inefficiency. Speculative decoding is the technique the source names as addressing this situation.
The commonly described pattern is this: a smaller draft model proposes several tokens ahead, and the main target model checks them together in one pass, keeping the proposals it accepts. The source pack gives only this motivation and not the full acceptance mechanism, so treat the steps below as the general pattern rather than a detail the source specifies.
The limits of speculative decoding follow from its motivation. It targets the bandwidth-bound, one-token-at-a-time step. If a workload is not dominated by that step, the gain it targets is smaller. The source pack does not enumerate other specific limits, so for any given serving stack, measure MFU and token-to-token latency before and after enabling it.
Mistakes Beginners Make with These Metrics
Common mistake Treating peak FLOP/s as the speed of your service
What it looks likeChoosing a chip because its spec sheet shows the highest peak number
Why it failsPeak FLOP/s describes the chip under chosen conditions. MFU describes your model on your workload.
Do this insteadMeasure MFU for your actual workload and compare that, alongside token-to-token latency.
Common mistake Ignoring input length when estimating latency
What it looks likeAssuming a 2,000-token prompt with a 20-token answer is cheap because the output is short
Why it failsThe source reports that 100 input tokens have roughly the same impact on overall latency as one output token.
Do this insteadCount input tokens as a real latency cost, not a free prefix.
Common mistake Assuming prompt caching reuses any shared text
What it looks likeExpecting a new prompt that shares only its first sentence with an old prompt to be served from cache
Why it failsSome implementations cache only whole prompts, so partial overlap may not help.
Do this insteadConfirm whether the system caches whole prompts, prefixes, or session messages in your version.
Common mistake Comparing TBT numbers with ITL numbers without checking that both describe the same delay between tokens
Trace the Cache: Practice Questions
A chip has a peak of 400 TFLOP/s. A workload achieves 100 TFLOP/s. Compute the MFU, then explain in one sentence whether buying a faster chip with a higher peak would necessarily improve this workload.
Hints
- Divide achieved FLOP/s by peak FLOP/s.
- Ask whether the workload can keep a faster chip busy, using the MFU idea that low utilization limits gains.
Two requests share the same 500-token system prompt. Request 1 arrives first, and request 2 arrives later with a different user query. Using the KV cache idea, which tokens does request 2 need to compute fresh, and what would change if the system prompt were edited between requests?
Hints
- Stable prefix tokens can be reused from the cache.
- A changed prefix is a different stored state, so the reuse no longer applies to the changed part.
Key Takeaways
- A higher peak FLOP/s number does not guarantee faster serving. MFU compares the work your workload actually accomplishes against what the chip could deliver, and matmul stalls on data movement can keep MFU low even on powerful hardware.
- Separating online and batch inference lets a service focus capacity on urgent, latency-sensitive requests first, while deferrable batch work is handled separately.
- KV cache prefilling stores the key and value state for the stable part of a prompt. A fixed system prompt makes that part reusable across many requests, so only the unpredictable user query must be computed fresh.
- Prompt caching depends on implementation: some systems cache only whole prompts, so partial overlap may not help. Speculative decoding targets the bandwidth-heavy one-token-at-a-time step, and its benefit depends on whether a workload is dominated by that step.