--max-num-seqs
1024 / 256 by card
A ceiling on the batch, not the batch you get.
▼Steadier per-token speed for those already in. Costs throughput, and lengthens the queue: the scheduler stops admitting at the ceiling.
▲Rarely moves anything: capacity binds first. Exception, short contexts on a 256-default card.
--gpu-memory-utilization
0.92
The share of the card vLLM will touch at all. Weights, activation peak and graph buffers come out of inside it.
▲0.95 is the cheapest capacity there is, though nothing like the largest.
●You court fragmentation or a co-tenant, not a long request: one that cannot get blocks is preempted, not crashed.
--max-num-batched-tokens
16,384 / 8,192 / 2,048 by card and launch
The per-step budget. Requests already generating come off the top, one token each.
▼Protects per-token speed for those already generating. Costs the newcomer's first token.
▲Does the reverse. No setting is correct. Floor: at least --max-num-seqs.
--enable-prefix-caching
on
Reuse, exact-match from the first token. Pays on a shared system prompt or a multi-turn chat, nothing on traffic that varies at the front.
●You do not turn this on. Check nobody turned it off.
●Check the hit rate before trusting a benchmark: warm and cold measure two different products.
--kv-cache-dtype fp8
off
Cache bytes. Halving them roughly doubles the conversations that fit.
▲Take it for the capacity.
●Then two checks: the backend line, because one without FP8 support falls back quietly; and your own eval, because the published accuracy evidence never touched the cache.
--enforce-eager
off
Compile and CUDA graph capture. Fast start, slower decode.
●Development only. A surprising amount of “vLLM is slow” is this, left on after debugging.
▲One exception: where capacity binds, the graph buffers it skips go back to the KV cache. Measure both ways.
The two defaults that depend on your card
| CARD | --max-num-seqs | TOKENS, OFFLINE | …API SERVER |
| B200 | 1024 | 16,384 | 8,192 |
| H100 | 1024 | 16,384 | 8,192 |
| H200 | 1024 | 16,384 | 8,192 |
| A100 | 256 | 8,192 | 2,048 |
| L40S | 256 | 8,192 | 2,048 |
Two tiers, not five cards: device memory, with one exception. Under 70 GiB you get the
smaller default, and the A100 gets it too, by name. Most people are serving, so most are on the shaded
column and do not know it. Both token columns double if you run --performance-mode throughput and have not set them yourself.
Which wall are you against?
Put vllm:num_requests_running against part one's ridge point for your
card — 296 on an H100, 153 on an A100, 419 on an L40S — and watch
vllm:num_preemptions_total.
CAPACITY
Preemptions climbing under load you used to handle. The memory fence and the 8-bit cache are where the room is.
LATENCY
Far under the ridge, no preemptions, and still missing your target. Capacity is fine, so the concurrency ceiling and the token budget are the pair to move.
NEITHER
Far under the ridge, no preemptions, and goodput where you want it. The defaults are already the right answer for you.