Hello, and welcome to the first module of this course. We will begin with the performance vocabulary that underlies GPU systems, distributed training, and LLM serving: latency, throughput, utilization, and concurrency. These quantities are easy to name but frequently misinterpreted in system-design discussions—especially when batching, queues, and multiple GPUs are involved.
This lesson develops a calculation-first framework for moving from timing data to operational conclusions: how busy a resource is, how much work is concurrently in the system, and whether latency is dominated by work itself or by waiting. These tools will recur throughout the course, from CUDA kernels to distributed training and production LLM services.
Four quantities, one carefully chosen boundary
Before calculating anything, draw a boundary around the system or resource you mean to analyze. It might be:
- an API request from admission to final response;
- a model-server replica;
- a GPU execution queue;
- a database connection pool;
- an entire multi-stage service.
The same request can have different latency and concurrency depending on that boundary. That is not a contradiction—it is the point of choosing one explicitly.
The core quantities are:
| Quantity | Symbol | Meaning | Typical unit |
|---|---|---|---|
| Latency / response time | or | Time from entering the chosen boundary to leaving it | ms, s |
| Service time | Time a resource actively spends processing work, excluding queueing | ms, s | |
| Queueing delay | Time waiting before service begins | ms, s | |
| Throughput | Rate of completed admitted work | requests/s, tokens/s | |
| Arrival rate | Rate at which work enters the boundary | requests/s | |
| Utilization | Fraction of available service capacity that is busy | fraction or percent | |
| In-flight concurrency | or | Average number of requests currently inside the boundary | requests |
For a request that visits one queue and one worker:
This decomposition is operationally useful:
- If dominates, reduce the amount of work or make the execution faster.
- If dominates, the resource is congested, scheduling is poor, traffic is bursty, or capacity is insufficient.
Do not call every delay “latency” and stop there. A 500 ms response could mean 490 ms of computation, or 10 ms of computation plus 490 ms waiting in a queue. The remedies are completely different.
Throughput is completed work, not “how fast one request feels”
Throughput is the long-run completion rate:
If a model-serving replica completes 18,000 requests over a five-minute steady-state interval:
For LLM serving, it is common—and necessary—to track at least two throughputs:
- Request throughput, e.g. requests/s.
- Token throughput, e.g. generated tokens/s.
Neither replaces the other. Request throughput reflects user-facing capacity, while token throughput better reflects model work for variable-length generations. A service can maintain a similar request rate while token throughput changes substantially if users begin requesting longer answers.
In a stable, lossless system over a sufficiently long interval:
That is, admitted work eventually completes, so rate in equals rate out. But there are important exceptions:
- During a short ramp-up or ramp-down interval, arrivals and completions need not match.
- With admission control, rejection, or dropped requests, offered arrival rate differs from admitted arrival rate.
- With retries, a “request” may enter downstream stages more than once.
- In a streaming LLM response, request completion rate and token emission rate describe different units of work.
For capacity and Little’s Law, use the rate associated with the exact boundary and the population you are measuring. If 150 requests/s arrive at a gateway but only 120 requests/s are admitted to the model server, use requests/s when analyzing the model-server queue.
Latency: use the right timestamp pair
Latency is simply a difference between timestamps—but the timestamps must match the question.
For an ordinary request:
For a stage within a pipeline:
In a production system, define timestamp ownership precisely. For example, “gateway arrival” might mean load balancer receipt, while “model admission” might mean the scheduler has accepted the request into a batchable queue. Those are both defensible boundaries, but they report different performance.
For LLM interactions, token streaming adds further user-relevant latency boundaries:

The detailed prefill/decode mechanics behind these LLM-specific measures come later. For now, notice the general rule: a latency metric must state its start event and end event. “Model latency” without those boundaries is not a useful metric.
Measure distributions, not only averages:
- Mean latency supports aggregate capacity calculations.
- p50 describes a typical request.
- p95/p99 show the tail experience and often reveal queueing, imbalance, long prompts, or noisy-neighbor effects.
- Maximum latency is usually too sensitive to isolated failures to summarize normal behavior.
A service can have an acceptable mean while violating a p99 objective badly. Nevertheless, Little’s Law uses a mean latency and an average in-flight count—not p99 latency.
Utilization: how much of a resource is actually busy
Utilization is the fraction of a resource’s available time spent doing work:
If a GPU is executing kernels for 42 seconds during a 60-second observation window:
For a single server that handles one request at a time, utilization can also be estimated from throughput and mean service time:
For homogeneous workers, each capable of handling one request at a time:
Equivalently, if each worker’s mean service rate is :
The denominator, , is the system’s idealized service capacity. A stable queue requires:
At , arrivals require at least as much capacity as the workers can provide. Queues then grow until some external mechanism intervenes: a timeout, rejection, client backoff, memory exhaustion, or system failure.
The important systems lesson is subtler than “keep utilization below 100%.” Queueing delay often rises sharply well before 100% because real workloads are variable:
- arrivals occur in bursts;
- request sizes differ;
- some requests are unusually slow;
- scheduling and load balancing are imperfect;
- garbage collection, communication stalls, or kernel variation create pauses.
Thus, a system designed to sit at 95–99% sustained utilization is usually designed to have poor tail latency. The appropriate headroom depends on workload variability and the latency objective; there is no universal safe percentage.
LISA17 - Queueing Theory in Practice: Performance Modeling for the Working Engineer
Watch “Queueing Theory in Practice: Performance Modeling for the Working Engineer” from USENIX for an engineer-oriented explanation of the latency knee: why delay is low at light load but climbs rapidly as utilization rises.
In the serial-systems portion, watch the model setup to see the assumptions behind a one-at-a-time server. Continue through queueing behavior, focusing on the distinction between actual service work and time spent waiting. Finish with the design implications: reducing service time and variability improves both latency and capacity.
One caution for GPU and LLM systems: direct busy-time utilization is always meaningful if defined clearly, but the simple formula needs care when a GPU processes a batch of requests simultaneously. A request may share GPU kernel execution with many others, so there may not be a clean per-request exclusive service time . In that setting:
- measure GPU utilization as busy GPU time divided by elapsed time;
- measure request throughput and token throughput separately;
- use empirical service curves under representative batch sizes rather than pretending each request owns an independent GPU interval.
Little’s Law: turning latency into concurrency
Little’s Law connects the average number of items inside a system to throughput and average latency:
where:
- is average in-flight concurrency;
- is throughput through the chosen boundary;
- is mean time spent inside that boundary.
It is unusually general. It does not require Poisson arrivals, exponential service times, FIFO scheduling, or a single server. It does require that the system be sufficiently stable over the measurement interval: work should not accumulate indefinitely, and the observed averages should be meaningful.
The units provide a valuable sanity check:
Suppose a stable service sustains requests/s and has mean end-to-end latency of ms:
On average, 18 requests are in flight: some executing, some waiting, perhaps some traversing network or serialization stages—depending on the boundary.
If you separately know mean service time is ms, then mean queueing delay is:
Little’s Law can be applied to the queue alone:
So approximately requests are waiting, on average. The remaining average work in service is:
The accounting checks out:
This is a powerful diagnosis. The end-to-end latency is 150 ms, but only 20 ms is active service. Faster compute might help, but this system’s immediate problem is evidently queueing.
Queuing Theory: Understanding Waiting Lines | Hongyu Hè
Read Hongyu Hè’s concise practical introduction to reinforce the performance vocabulary, Little’s Law, and the discipline of applying it to a clearly chosen system boundary.
Start with the opening metric definitions in “Key performance metrics” and read the metric overview. Then read the “Little’s Law” subsection and its in-flight-request example. Continue to “Utilization and the stability condition,” focusing on the utilization formula and why utilization at or above one is unstable. Finally, in “Practical Modeling Workflow,” use the five-step workflow as a checklist for translating production telemetry into a first-order model.
Worked capacity calculation from workload timing data
Consider a model-serving fleet with four identical request workers. Over a stable 10-minute interval, monitoring reports:
- completed requests: ;
- mean request latency from model admission to final response: ms;
- mean active worker service time per request: ms;
- no rejected requests during the interval.
1. Compute throughput
2. Compute average in-flight concurrency
Convert milliseconds to seconds:
Then apply Little’s Law:
There are 18 requests in the model-serving boundary on average.
3. Compute worker utilization
There are workers, each with mean service time s:
Each worker is busy about 60% of the time, on average.
The implied per-worker service rate is:
Total idealized service capacity is:
At 120 requests/s, the offered load is , matching the utilization calculation.
4. Separate queueing from service
Interpretation:
- about requests are actively being served across the four workers;
- about requests are waiting, on average;
- mean latency is queueing-dominated despite moderate aggregate utilization.
That last point should prompt investigation rather than an automatic conclusion. Possible explanations include bursty arrivals, unequal worker load, serial stages hidden within “service,” admission/scheduling delay, or a mismatch between the modeled boundary and the timestamps used.
Applying the same logic to LLM serving
Suppose an LLM service runs for 60 seconds under a representative workload and observes:
- 300 completed requests;
- 36,000 output tokens generated;
- 8 s mean request latency from admission to final token;
- 75% measured GPU busy utilization.
First, report both rates:
Now use request throughput—not output token throughput—for request concurrency:
The service has, on average, 40 admitted requests in flight.
This does not mean that 40 requests are executing one per GPU. Some may be awaiting prefill, some may be included in a batch, and some may be awaiting their next decode step. The average is still useful: it informs queue capacity, scheduler limits, cancellation behavior, and memory budgeting. But interpretation requires knowledge of the serving engine.
It would be incorrect to compute request utilization as . That quantity is concurrency, not utilization. It would also be incorrect to infer that a 75% busy GPU has 25% spare request capacity: the next requests may have longer prompts, larger KV-cache footprints, or poor batch compatibility.
For LLM serving, use the following mental separation:
| Question | Appropriate quantity |
|---|---|
| How many user requests are active or queued? | |
| How much model generation is happening? | output token throughput |
| How busy is the GPU? | measured GPU busy-time utilization |
| Is queueing hurting users? | queue time plus TTFT and tail latency |
| Can another request fit in memory? | KV-cache and batch-capacity analysis |
We will later connect these metrics to prefill, decode, continuous batching, KV-cache capacity, and the distinct behavior of token streaming.
A reliable measurement workflow
When given a dashboard, trace, or interview-style timing table, work through this sequence.
-
Choose the system boundary.
State where a request enters and leaves. Do not combine gateway arrival rate with GPU-only latency. -
Choose a steady-state interval.
Exclude deployment warm-up, model loading, synthetic-test ramp phases, and outages unless the goal is explicitly to analyze them. -
Compute throughput from completions.
where is completions in duration .
-
Compute mean latency from matching request timestamps.
Use the same boundary as throughput. Retain p50, p95, and p99 alongside the mean. -
Estimate in-flight work with Little’s Law.
-
Compute utilization at a specific resource.
Prefer direct busy-time measurement:Or use only where represents well-defined per-job service demand on equivalent servers.
-
Validate using independent evidence.
If Little’s Law predicts , compare it with time-averaged in-flight gauges, scheduler queue depth plus active requests, or trace-derived concurrency. A large discrepancy usually indicates mismatched boundaries, unstable traffic, dropped work, incorrect units, or a biased sampling method.
Two common mistakes are worth making explicit:
-
Mixing milliseconds and seconds.
At requests/s and ms latency:not 50,000.
-
Using p99 latency in Little’s Law.
Little’s Law relates average occupancy to average time. Tail latency is essential for SLOs, but it does not directly substitute into this equation.
Closed-loop clients and “think time”
A final boundary issue matters for load testing and interactive applications. A closed-loop client alternates between issuing a request and waiting, perhaps with think time or pacing:
For this broader client-loop boundary:
Think time belongs in the equation only if your boundary includes the client loop. It does not belong in server-side in-flight concurrency.
This distinction explains why a test may need 100 virtual users to produce 20 requests/s while the server itself has only 10 requests in flight. The remaining users are reading, waiting, or pacing before their next request.
Key takeaways
- Latency is time inside a specified boundary; distinguish active service time from queueing delay.
- Throughput is the completion rate of a well-defined unit: requests, tokens, jobs, or batches.
- Utilization is the busy fraction of a particular resource. For homogeneous one-job-at-a-time workers, .
- Little’s Law connects mean concurrency, throughput, and mean latency:
- Stable systems have admitted arrival rate approximately equal to completion throughput; rejected, retried, or ramping traffic needs more careful accounting.
- In batched LLM inference, request concurrency, token throughput, and GPU utilization are all necessary—but they are not interchangeable.
Next, we will use Amdahl’s Law to estimate the maximum end-to-end benefit of an optimization. That will provide a disciplined way to answer a common infrastructure question: if we accelerate one part of the workload, how much faster can the whole system actually become?
Can't find a good explanation? Sign up and we'll make it for you
Sign up