TT Lab
Blog

한국어 English 日本語 中文

Get started
Blog

Blog

vLLM Feature Map: What Exists, When It Benefits, and What Changed in Each Version

Status: Draft (2026-10-27), partially measured. Feature lists and options were verified directly on 2026-10-27 from the official vLLM 0.32.0 documentation (repository docs/) and release notes from 0.8.0 to 0.32.0. Measurements were conducted using the official 0.31.0 (released 2026-10-05) container. The 0.32.0 image was not used as it required a fresh download, and discrepancies between the two versions' documentation are noted in each section. Added on 2026-10-27. Upon receiving approval, measurements were retaken using the vLLM 0.32.0 image along with Qwen3-0.6B, Qwen3-0.6B-GPTQ-Int8, Qwen3-4B-AWQ, and Qwen3-VL-2B-Instruct. A comparison of the two versions was added to Section 3-1, and a "Re-measurement on 2026-10-27" subsection was added to each part. The 0.31.0 figures were not removed. Writing Rules: Measured data serves as the baseline; unmeasured items are marked as "Unmeasured", and unverified items are marked as "Unverified".

Table of Contents

1. What This Series Covers

vLLM is a serving engine for language models. It started with PagedAttention (Kwon et al., SOSP 2023), but now includes a vast array of features such as schedulers, caches, decoding acceleration, output enforcement, quantization, multi-GPU support, and operational tools. This site already features several articles covering vLLM.

This series focuses on filling in the features not covered by those articles. Overlapping features are summarized briefly and linked to previous articles.

Part Covered Features Measurement
1 Feature map, version changes Summary
2 Continuous batching, chunked prefill, prefix caching, cache_salt Repeated measurements, baseline with features disabled
3 Speculative decoding (n-gram, EAGLE, MTP, suffix) Two n-gram implementations, proposal length, concurrency
4 Structured outputs (xgrammar, guidance) Correctness, first-request cost, cost per token
5 Tool calling (parser, tool_choice, strict) Schema compliance rate
6 Quantization (FP8, AWQ, GPTQ, KV FP8) Online FP8, perplexity
7 KV offloading and disaggregated serving CPU offloading
8 Sleep mode, startup time, /metrics, authentication Sleep, compilation cache, path-based authentication
9 Parallelism, multimodal, pooling, LoRA Embedding and reranking only

2. Feature Map

"What it saves" refers to the cost reduced by the feature, and "Benefit conditions" are the conditions where effectiveness was observed in measurements or documentation.

Feature Principle (Paper) Enabling Option (v0.31/v0.32) Default What It Saves Benefit Conditions Non-Benefit Conditions
PagedAttention KV in blocks (Kwon et al., SOSP 2023) Always Enabled KV memory waste When request lengths vary widely N/A
Continuous batching Iteration-level scheduling (Yu et al., OSDI 2022) --max-num-seqs 256 Empty batch slots When concurrent requests are high When there is only a single request
Chunked prefill Splitting prefill and mixing with decode (Sarathi) --max-num-batched-tokens Enabled, 2,048 (servers with GPUs under 70GB) Decode stall time When long inputs and decodes are mixed When only short inputs arrive
Prefix caching KV reuse via block hashes --enable-prefix-caching Enabled Prefill computation When shared prefixes are long and frequent When the prefix differs every time
cache_salt Salt on the first block hash Request's cache_salt None Timing leaks between tenants When multiple clients share an engine Single user
Speculative decoding Verifying drafts in batch (Leviathan et al., ICML 2023) --speculative-config Disabled Decode steps When concurrency is low and outputs are predictable High concurrency, random outputs
Structured output Token masking (XGrammar, MLSys 2025) response_format, structured_outputs auto Format errors Machine-readable outputs Free-form text
Tool calling Parser + structural tags --enable-auto-tool-choice --tool-call-parser Disabled Call parsing errors Agents Models unfamiliar with tools
Weight quantization FP8, AWQ, GPTQ --quantization None Weight memory and reads Low concurrency, large models Large batch
KV quantization KV FP8 --kv-cache-dtype fp8 auto (model precision) KV memory When KV is scarce When KV is ample
Multi-LoRA Adapter Batching Computation (Punica, S-LoRA) --enable-lora --max-loras Off Number of model ranks When there are multiple adapters When there is a single adapter
KV Offloading KV connector, CPU tier --kv-offloading-size Off Recomputation of evicted prefixes When GPU KV is insufficient and there is reuse When there is no reuse
Disaggregated Serving Prefill-Decode Disaggregation (DistServe, OSDI 2024) --kv-transfer-config(NIXL, etc.) Off Tail ITL Fast inter-GPU connection Slow connection, throughput goal
Parallelization TP, PP, DP, EP Megatron-LM, etc. --tensor-parallel-size , etc. 1 Limitations of a single GPU When the model does not fit When the model fits
Sleep Mode CuMem Allocator --enable-sleep-mode + Dev Mode Off Restart time When alternating GPUs Always-on serving
Multimodal and Pooling Encoder, LAST/CLS pooling Depends on the model, --runner pooling Depends on the model Separate server Unified with the same engine When a specialized engine is faster

OpenAI-compatible APIs (/v1/completions, /v1/chat/completions, /v1/embeddings, /v1/responses , etc.) and /metrics were omitted from the table because they act as gateways to all of these features rather than being features themselves. All measurements in this series were performed using this API, and the metrics are gathered in Part 8.

Some features cannot be used together. According to the compatibility table in the 0.32.0 documentation, speculative decoding cannot be used alongside LoRA, pooling, or prompt embedding inputs (❌). Even during our actual measurements, version 0.31.0 emitted warnings when n-gram speculative decoding was enabled, stating "Disabling asynchronous schedule" and "Model Runner V2 does not yet support ngram, falling back to V1 runner."

3. Summary of Measured Values

All measurements were conducted on a single 8GB laptop GPU (Ada generation) with vLLM 0.31.0, Qwen3-Reranker-0.6B (bf16, a 0.6B causal language model fine-tuned for reranking), and a container memory limit of 4GiB or 4.5GiB. The same conditions were repeated three to four times to take the median, and the first batch after spinning up the server was excluded as warmup.

Feature Condition Result (Median)
Continuous Batching Concurrency 16, Input 256 / Output 128 One by one 174.6 tok/s → Default 1,683.1 tok/s (9.6x)
Chunked Prefill 3,700-token input during decoding Max decode stop 512-token chunk 35.6ms, Default 109.8ms, Chunk disabled 197.6ms
Prefix Cache 3,200 common tokens First token 174.7ms → 18.9ms, Disabled 173.8ms
cache_salt Same prefix, different salt Different salt results in 0 cached tokens, 173.7ms
N-gram Speculative Decoding Concurrency 1, text copying 176.4 → 704.1 tok/s (4 drafts, 4.0x), 8 drafts 1,117.0 tok/s (6.3x), acceptance rate over 96%
N-gram Speculative Decoding Concurrency 1, random output One prompt set with a low acceptance rate became 10% slower (171.4 → 153.6 tok/s). 14% decrease in throughput at concurrency 32
Structured Outputs JSON Schema, Concurrency 16 Valid JSON 46/48 (2 incorrect due to length excess), none 0/48. First request 446ms (xgrammar)
Tool Calling required, strict none/present Schema compliance 0/5 → 5/5, values are incorrect
FP8 Online Quantization Concurrency 1/16/64 Throughput 1.36/1.24/1.08x, weights 1.12 → 0.71GiB
KV CPU Offloading Evicted 1,600-token prefix Recomputation 77.3ms → 35.1ms on CPU (GPU hit 14.0ms)
Sleep Mode Level 2, Level 1 Level 2: GPU 6,168 → 606MiB, Wake-up 0.39s (restart 32s), identical output. Level 1: Container OOM twice
Startup Time Restart with same configuration 65s → 32s (compilation cache)
Auth --api-key /v1/* 401, /invocations 200 (generation run)
Embedding and Reranking 64 sentences, 32 documents 371.8ms, 33.9ms

Features that were not measured include tensor, pipeline, data, and expert parallelism (single GPU), disaggregated serving (for the same reason), and EAGLE, MTP, and suffix speculative decoding. EAGLE was skipped because draft weights (pickle format with its own license) and suffix require additional packages. Multimodal inputs and AWQ/GPTQ, which were unmeasured in the initial edition, were measured in the remeasurement in Section 3-1.

3-1. October 27, 2026 Remeasurement: 0.32.0 and Chat Models

Feature Oct 27, 2026 0.31.0 Measurement (Reranking 0.6B) 0.32.0 Remeasurement
Continuous Batching, Chunk, Prefix Cache 9.6x, 109.8ms, 174.7 → 18.9ms Identical within 1.5% with the same model (1,683.6 tok/s, 108.2ms, 175.2 → 18.9ms)
Auth (/invocations) 200 without key 200 without key (unchanged)
Sleep Level 2 and Level 1 Wake-up 0.39s, Level 1 container OOM Wake-up 0.41s, Level 1 OOM again
N-gram Speculative Decoding Copying 4.0x, greedy output 10/12 match, KV decreased by 23% Qwen3-0.6B: Copying 3.7x, code return 3.1x, Explanation 0.97x (3% acceptance), greedy output 12/12 match, KV decreased by 2% (V2 runner)
Structured Outputs Valid JSON 0/48 without enforcement Qwen3-0.6B: Values were correct 18/18 even without enforcement, but readability failed 0/18 due to code fences; 18/18 when enforced
Tool Calling Schema compliance 0/5 without strict Qwen3-0.6B, GPTQ, 4B AWQ: All 36/36 cities and units correct, including auto
Quantization FP8 1.36x Qwen3-0.6B: FP8 1.37x, GPTQ 8-bit 1.40x (perplexity -1.4% / +1.6%). 4B AWQ achieves 80 tokens per second on 8GB
Multimodal Not measured VL-2B default setting failed to start with KV -0.07GiB, KV 2.13GiB with size hint. 896px image 808 tokens, first token 238ms, 32.7ms for the same image again. The default setting actually fetches internal addresses

Limitations of this measurement

4. What Changed Across Versions

vLLM releases a new version about every two weeks. I have picked out only the changes that matter when reading previous posts or migrating old configurations (checked from the release notes).

Version Changes
0.8.0 V1 engine becomes the default
0.10.0 Started cleaning up V0 engine code (removed V0's speculative decoding workers, etc.)
0.11.0 Completely removed V0 engine. Introduced CPU KV offloading (LRU). Prefix cache hash default is sha256 (according to documentation)
0.12.0 guided_json , etc. guided_* Removed request field, structured_outputs unified to
0.14.0 Asynchronous scheduling (overlapping engine scheduling and GPU execution) is the default
0.19.0 General-purpose CPU KV offloading (swappable policy)
0.21.0 Strict tool calling with xgrammar structural tags
0.28.0 for large GPUs, max_num_batched_tokens Default 8,192 → 16,384
0.29.0 Model Runner V2 is now the default for all models
0.31.0 Online quantization --quantization fp8 has fp8_per_tensor moved to (check for warnings in actual measurements)
0.32.0 max_tokens is no longer pruned from the context in advance (long prompts are no longer rejected). Default CORS is "No Access". Cascade attention removed. Python 3.10 support dropped. JSON schemas nested more than 64 levels deep are rejected. GPU n-gram proposer added to MRV2

Some features that disappeared during the transition from V0 to V1 are also missing. The V1 guide in 0.32.0 best_of, per-request logit processors, GPU↔CPU KV exchange (swap on preemption), and per-request structured output backends are marked as "Removed". In V1, preemption defaults to recomputation (RECOMPUTE) rather than swapping.

5. Where to start

References

Sign in to like

Comments

No comments yet.

Sign in to leave a comment