What the server does with your request
Every request has two phases with different costs, and four numbers tell you how a server handles them for all its users.
You sent two requests in section 1.1, and both came back in under a second. With ten users, the same server can make some of them wait seconds for the first word. The reason is in the two phases of every request.
When you finish this section, you can name the two phases of a request and the four numbers a server is judged by. You can also say what SGLang controls and what stays with the model and with you.
Two phases with two different costs
Prefill: the forward pass over the whole prompt. It computes the keys and values of every prompt token in one batch and produces the first output token. Decode: the loop that produces each next token, one forward pass per token per request.
The two phases use the GPU in different ways. Prefill has many tokens in each pass, so it keeps the arithmetic units busy. Decode has one new token per request in each pass.
Each decode step reads the weights that the step needs, and the cached keys and values, to do little arithmetic. For a dense model, that is every weight. For a mixture-of-experts model, it is the shared weights and the experts that the router chose. Memory bandwidth sets the speed of decode, and compute sets the speed of prefill.
We measured the difference on a Mac with a 0.6B model. A 512-token prompt reached its first token in a median of 163 ms. After that, each new token took 4.38 ms on average.
Max request concurrency: 1
Successful requests: 16
…
Median TTFT (ms): 162.98
…
Mean TPOT (ms): 4.38 That is at most about 0.32 ms per prompt token against 4.38 ms per output token, a factor of about 14 on this Mac. The 0.32 ms is an upper bound, because the TTFT also holds the queue and the first decode step. On our L4 with Qwen3-8B the factor was about 160: 189 ms for a 512-token prompt, against 60 ms per output token. A serving engine can share and skip prefill work. It mostly batches decode work, so that one read of the weights serves many requests. Section 4.4 shows the other way to cut decode steps.
The four numbers
Judge a server by four numbers together. A report that gives one of them tells you little.
- Time to first token (TTFT): how long a user waits before the first word. Prefill and the queue set it.
- Time per output token (TPOT): the average gap between tokens after the first. Inter-token latency (ITL) is the same gap, measured one token at a time, so its tail shows stalls. Decode sets both.
- Throughput: output tokens per second across all users. Batching sets it.
- Goodput: requests per second that meet a TTFT target and a TPOT target at the same time. Your users feel this number.
The first three trade against each other. A larger batch raises throughput and makes the tokens of each user slower. A large prefill chunk finishes a long prompt sooner and stalls every decode in the batch while it runs. Section 5.1 shows the trade on a real sweep.
The SGLang benchmark tool prints TTFT, TPOT, ITL, and throughput. It does not print goodput at version 0.5.22, so compute it from the records of each request. The inference metrics lesson builds that calculation.
What SGLang owns, and what it does not
SGLang owns the time between a request and its tokens. It decides which prompt tokens to compute, which to reuse, and when each request runs.
Three things stay outside. The model decides what the answer says. On our Mac, a 0.6B model asked to name a planet answered "Ardens", which is no planet. SGLang served that answer correctly and fast, and no serving engine can make a model right.
You, the operator, decide how much memory SGLang gets and which machine a request goes to. SGLang has a separate router for that second job, and section 6.4 covers it.
The path of one request
Inside SGLang, your /generate request crossed three processes. The tokenizer manager turned the text into token ids. The scheduler found two of the five prompt tokens in the cache and computed the other three. The detokenizer turned the new token ids into text.
The scheduler logged its side of the request in one line:
[2026-10-17 14:43:41] Prefill batch, #new-seq: 1, #new-token: 3, #cached-token: 2, token usage: 0.00, #running-req: 0, #queue-req: 0, #pending-token: 0, cuda graph: True, input throughput (token/s): 2.82
[2026-10-17 14:43:41] INFO: 127.0.0.1:58314 - "POST /generate HTTP/1.1" 200 OK#new-token: 3 and #cached-token: 2 add up to the five prompt tokens. This pair is the most useful line that SGLang prints. Section 3.4 uses it alone to find a prompt that misses the cache.
Our position
Choose SGLang for the shape of your traffic, never for a headline number. Agents, chat with a fixed system prompt, and retrieval with a fixed preamble all share long prefixes. For that traffic, the prefix cache saves prefill work on every request. If every prompt is unique and long, measure two engines on your own prompts before you decide.
Distrust any SGLang benchmark that does not name its version. The most repeated number on the web, "SGLang 29% faster than vLLM", comes from one offline test that lists SGLang v0.2.3. Section 5.3 shows where independent tests agree, and our own head-to-head runs.
To see how the scheduler, the cache, and each forward pass do this work, read Parts 2 to 4. Start with section 2.1, which follows the request through the three processes.
SGLang 0.5.22 · baa9bef · 2026-10-13 · Edition 2026.10