LLM serving engines compared on the Pareto frontier: vLLM, SGLang, TRT-LLM and Dynamo

Contents

Notation: amounts in euros (N €), decimals with a point. The dollar symbol is not used (on this site it is a formula delimiter). Reference hardware: generic configuration 4×H100 SXM 80 GB; the figures are illustrative for comparing engines, not production metrics from any real infrastructure.

TL;DR

Four OSS engines dominate on-premise LLM serving in 2026: vLLM, SGLang, NVIDIA TensorRT-LLM and NVIDIA Dynamo. None is superior on every axis. In raw throughput with a shared prompt, SGLang beats vLLM by 29 % on Llama-3.3-70B FP8 over H100 (16,200 vs 12,500 tok/s). In decode latency, TRT-LLM keeps ITL more stable at high concurrency (9–12 ms P50 against 18–22 ms for vLLM). Dynamo is not an inference engine: it is the orchestration layer on top of the previous three for multi-node clusters, and it reports up to 7× additional throughput in disaggregated serving on Blackwell. The right choice depends on three variables: load pattern (batch/interactive), deployment scale (single node/multi-node) and operational constraints (OSS maturity, ease of operation). The Pareto decision table is at the end of the article.


Framing the article: what this B8 is and is not

This article (B8 of the benchmarking pillar) takes for granted the metrics from the introduction to benchmarking and the tool catalogue from the card-by-card piece. It applies those concepts to engine selection. The protocol from GuideLLM for SLO validation and AIPerf in depth detail how to run the harness; here the result is used. The fundamentals of continuous batching, disaggregated serving, the attention backend and quantisation are assumed known.


Card for each engine

vLLM

AttributeValue
Reference versionv0.9.x (June 2026)
LicenceApache 2.0
Maintainer / governancevLLM Project (Linux Foundation AI), led by UC Berkeley + Red Hat
Supported hardwareNVIDIA (Ampere/Hopper/Blackwell), AMD ROCm, Intel Gaudi, TPU, CPU
Repositorygithub.com/vllm-project/vllm
APIOpenAI-compatible (completions, chat, embeddings)

Origin: PagedAttention (Kwon et al., 2023). The first implementation of continuous batching with a paged KV cache. In 2026 it is the most deployed engine in OSS environments and the one that accumulates the most integrations (Ray Serve, Kubernetes, llm-d, Dynamo).

SGLang

AttributeValue
Reference versionv0.4.x (June 2026)
LicenceApache 2.0
Maintainer / governanceLMSYS Org (Berkeley, CMU, UCSD)
Supported hardwareNVIDIA (Ampere/Hopper/Blackwell), AMD ROCm
Repositorygithub.com/sgl-project/sglang
APIOpenAI-compatible + SGLang runtime API

Origin: the SGLang paper, 2024 (Zheng et al.). It introduces RadixAttention as a generalisation of prefix caching: a radix tree of KV blocks with an LRU policy shared across all in-flight requests. A structural advantage in workloads with shared prefixes (long system prompts, few-shot, RAG).

NVIDIA TensorRT-LLM (TRT-LLM)

AttributeValue
Reference versionv0.18.x (June 2026)
LicenceApache 2.0
Maintainer / governanceNVIDIA (proprietary in practice, OSS in name)
Supported hardwareNVIDIA only: Ampere (A100), Hopper (H100/H200/GH200), Ada (L40/L40S), Blackwell (B200/GB200)
Repositorygithub.com/NVIDIA/TensorRT-LLM
APIPython + C++ runtime; integrates with Triton Inference Server

The lowest-level engine: it compiles inference graphs with TensorRT, applies kernel fusion and generates binary engines specific to model + hardware + precision. Maximum performance on NVIDIA, with no portability to other hardware. It requires recompilation when the model or configuration changes; build time ranges from minutes to hours depending on the model.

NVIDIA Dynamo

AttributeValue
Reference versionv1.1.1 (May 2026)
LicenceApache 2.0
Maintainer / governanceNVIDIA + OSS community (ai-dynamo org on GitHub)
Supported hardwareNVIDIA (through the underlying engine: vLLM, SGLang or TRT-LLM)
Repositorygithub.com/ai-dynamo/dynamo
RoleOrchestration layer, NOT an inference engine

Dynamo does not run inference directly: it is the scheduler and router that coordinates pools of workers (vLLM, SGLang, TRT-LLM) across multiple nodes. Implemented in Rust (performance) + Python (extensibility). It adds: disaggregated prefill/decode serving across nodes, KV-aware routing (avoiding prefill recompute if another worker already has the KV in cache), automatic scaling by SLA, a KV Block Manager (KVBM) with offload to CPU/SSD/remote and transfer via NIXL over NVLink/InfiniBand.

Honourable mentions: LMDeploy and HF TGI

LMDeploy (OpenMMLab/InternLM, Apache 2.0): an engine with two backends, TurboMind (C++, maximum performance on NVIDIA) and PyTorch (flexibility). KV cache blocking and persistent batching; 4-bit inference up to 2.4× faster than FP16 in its own benchmark. A narrower ecosystem; no AMD support.

HF TGI (Hugging Face, Apache 2.0): the reference engine for the HuggingFace ecosystem. TGI v3.0 cuts latency by up to 13× on long prompts against earlier versions; it integrates FlashAttention + PagedAttention. The usual entry point for teams already operating the HF stack; it is not the most efficient in throughput at maximum load.


Capability matrix

The table uses this notation: Yes = supported and stable, Beta = available but not recommended for production, No = not available or only with a manual workaround.

CapabilityvLLMSGLangTRT-LLMDynamo (via backend)
Continuous batchingYesYesYesYes (delegates to the engine)
PagedAttentionYesYesYesYes
RadixAttention / prefix cachingYes (chunked prefill + prefix)Yes (native RadixAttention)Yes (prefix caching)Yes + KV-aware routing
Speculative decodingYes (n-gram, EAGLE, DFlash, suffix)Yes (draft+verify)Yes (EAGLE-3, MTP)Yes
FP8 quantisationYesYesYesYes
MXFP4/NVFP4 quantisationYesBetaYes (Blackwell)Yes
INT4 AWQ quantisationYesYesYesYes
GPTQ quantisationYesYesNot nativeYes (via vLLM)
INT8 quantisation (SmoothQuant)YesYesYesYes
Structured outputYesYes (compressed FSM)BetaYes
Dynamic multi-LoRAYesYesBetaYes
Disaggregated prefill/decodeBeta (experimental)YesYesYes (first class)
Chunked prefillYesYesYesYes
Multimodal support (VLM)YesYesYesYes
Multi-node tensor parallelismYesYesYesYes (+ pipeline across nodes)
OpenAI API compatibleYesYesYes (via Triton)Yes
Non-NVIDIA hardwareYes (AMD/Intel/TPU)Yes (AMD)NoNo

Sources for the matrix: docs.vllm.ai, docs.sglang.io, nvidia.github.io/TensorRT-LLM, docs.nvidia.com/dynamo, github.com/ai-dynamo/dynamo (feature matrix, June 2026).


Why they are not compared lightly: the variables that break a comparison

Before the table of figures, the four decisions that invalidate any cross-engine benchmark:

1. A different harness. A benchmark run with each engine’s native micro-bench (vllm bench serve vs SGLang bench) measures the client, not the engine. The discrepancy can be up to 7.2× at high concurrency. The correct protocol: a single load generator (AIPerf or GuideLLM) against every endpoint. The engine is the variable, the tool is the constant.

2. Different ISL/OSL. Input Sequence Length and Output Sequence Length determine the prefill/decode ratio and therefore which engine is favoured. A benchmark with low ISL (64 tokens) favours engines with fast decode; with high ISL (2,048 tokens) and shared prefixes, it favours SGLang (RadixAttention). Fixing ISL and OSL is mandatory for the comparison to be valid.

3. Different precision. FP16 and FP8 are not comparable: FP8 gives between 1.5× and 2× more throughput on Hopper. Comparing vLLM FP16 with TRT-LLM FP8 says nothing about the engine.

4. Not reporting P99. Maximum throughput is reached at the point where TTFT P99 already violates the SLO. The defensible number is goodput, throughput under the SLO, not the raw maximum. The end-to-end latency formula:

$$\text{latency}_{e2e} \approx \text{TTFT} + (N_{\text{out}} - 1) \times \text{TPOT}$$

where \(N_{\text{out}}\) is the number of output tokens, makes it clear that a high TTFT with low TPOT has the same effect as the inverse case only for one specific \(N_{\text{out}}\): both must be reported separately.

The complete fair-comparison protocol is in the tools article.


Performance on the Pareto frontier: illustrative figures

Reference configuration for every row: 4×H100 SXM 80 GB NVLink, model Llama-3.1-70B-Instruct FP8, harness AIPerf (formerly genai-perf, the multi-process successor), dataset ShareGPT (realistic length distribution), mean ISL ~512 tok, mean OSL ~256 tok, SLO TTFT P99 < 500 ms. The figures are illustrative and representative of benchmarks published by the community (Cerebrium, LMSYS, Spheron, Red Hat MLPerf v5.1); they are not measurements from any real infrastructure. Exact figures vary with engine versions, compilation flags and load distribution.

Throughput vs latency: Pareto table

EngineConfigThroughput (tok/s)TTFT P50 (ms)TTFT P99 (ms)ITL P50 (ms)Goodput (@SLO)
vLLM v0.9FP8, chunked prefill12,50016042018~96 %
SGLang v0.4FP8, RadixAttention16,20014039021~97 %
TRT-LLM v0.18FP8, compiled engine14,80019048010~93 %
vLLM + DynamoFP8, disagg. P/D 2+218,50012031019~98 %
SGLang + DynamoFP8, disagg. P/D 2+221,00011028022~99 %
TRT-LLM + DynamoFP8, disagg. P/D 2+222,50013035011~97 %

Reading notes:

  • “Disagg. P/D 2+2” = 2 prefill GPUs + 2 decode GPUs (the same 4×H100 budget).
  • Goodput falls against raw throughput when the latency tail exceeds the SLO of 500 ms P99. TRT-LLM without Dynamo has the lowest ITL but the highest TTFT at high concurrency, which brings its goodput down to ~93 % under this SLO.
  • Dynamo adds ~30–40 % of effective throughput over 4 GPUs thanks to disaggregated serving and KV-aware routing, in the scenario with reusable prefixes (ShareGPT).
  • In workloads without shared prefixes (short ISL, unique prompts), Dynamo’s advantage shrinks to ~10–15 % over the base engine.

Saturation point (concurrency sweep, vLLM FP8, 4×H100)

ConcurrencyTTFT P99 (ms)ITL P50 (ms)Throughput (tok/s)Goodput (tok/s)
8210145,2005,200
16370189,8009,800
324201812,50012,200
486802613,8007,400
641,2004114,1002,100

The knee is between 32 and 48: throughput rises only 10 % (12,500 → 13,800) but TTFT P99 already violates the 500 ms SLO and goodput halves. The defensible operational capacity is the one at concurrency 32 (12,200 useful tok/s). Reporting 14,100 tok/s (concurrency 64) would be maximum throughput with 15 % goodput.

TTFT P99 (ms) ↑ lower is betterThroughput (tok/s) → higher is betterSLO 500 msvLLM12,500 tok/s · 420 msSGLang16,200 tok/s · 390 msTRT-LLM14,800 tok/s · 480 msvLLM+Dynamo18,500 tok/s · 310 msSGLang+Dynamo21,000 tok/s · 280 msTRT-LLM+Dynamo22,500 tok/s · 350 ms012 K16 K18.5 K21 K22.5 K

Fair-comparison methodology: the harness as the constant

The protocol that makes numbers comparable across different engines. The engine is the only variable; everything else is constant and pinned in the output JSON.

Variables that are fixed (constants of the experiment)

VariableValue fixed in the reference experiment
Load toolAIPerf v2.x (multi-process)
ModelLlama-3.1-70B-Instruct
PrecisionFP8
Hardware4×H100 SXM 80 GB NVLink
DatasetShareGPT (realistic ISL/OSL distribution)
SLOTTFT P99 < 500 ms, ITL P50 < 30 ms
Warm-up200 requests discarded before measuring
Sweepconcurrencies 1, 4, 8, 16, 32, 48, 64
Primary metricgoodput (useful tok/s under SLO)

Harness steps

  1. Deploy the engine with the exact config (pinned flags, fixed version).
  2. Warm-up: 200 requests; discard the results.
  3. Concurrency sweep: aiperf profile --concurrency-range 1:64:step with AIPerf.
  4. Extend the sweep past the knee (until goodput falls below 50 %).
  5. Collect the JSON: TTFT P50/P99, ITL P50, raw throughput, goodput.
  6. Change only the engine; repeat steps 1–5.
  7. Compare the goodput column across rows.

The sweep with GuideLLM is equivalent for SLO validation; AIPerf is preferable for engine comparisons because its automatic estimatedCapacity normalises the saturation point. Both can be used: GuideLLM for the operational SLO, AIPerf for reference capacity.

Reproducible output format

{
  "harness": "aiperf", "harness_version": "2.x",
  "model": "Llama-3.1-70B-Instruct", "precision": "FP8",
  "hardware": "4xH100_SXM_80GB_NVLink",
  "dataset": "sharegpt",
  "slo": {"ttft_p99_ms": 500, "itl_p50_ms": 30},
  "motor": "vllm", "motor_version": "0.9.x",
  "concurrency_sweep": [8, 16, 32, 48, 64],
  "results_at_knee": {
    "concurrency": 32,
    "ttft_p50_ms": 210, "ttft_p99_ms": 420,
    "itl_p50_ms": 18, "throughput_tok_s": 12500,
    "goodput_tok_s": 12200
  }
}

This versioned JSON is the auditable datum: anyone can reproduce the figure with the same tool, version, model, hardware and load.


State of the art 2026: relative maturity

DimensionvLLMSGLangTRT-LLMDynamo
Production maturityHigh (3+ years)Medium-high (2 years)High (NVIDIA)Medium (1.0 GA Mar 2026)
Release cadenceWeeklyWeeklyMonthlyFortnightly
Integration ecosystemVery broad (Ray, k8s, llm-d, Dynamo, NIM)Broad (Dynamo, k8s)NVIDIA-centric (Triton, NIM)NVIDIA-centric
Ease of operationHigh (pip install, OpenAI API)HighMedium (requires compiling engines)Medium-low (multi-node, etcd/NATS)
Non-NVIDIA hardwareYes (AMD, Intel, TPU)Yes (AMD)NoNo
Disaggregated servingBetaStableStableFirst class
Dynamic multi-LoRAStableStableBetaStable (via vLLM/SGLang)
Structured outputStableStable (FSM)BetaStable (via the engine)
OSS community supportVery high (>30 K GitHub stars)High (~20 K stars)High (~10 K stars)Growing (6.8 K stars)

Pareto decision table: when to choose each engine

No prose; the decision as a table of criteria and outcome.

Selection criterionRecommended engineQuantitative justification
Single node, quick prototype, team with no LLM serving experiencevLLMpip install + OpenAI API in minutes; the broadest community support
Workload with long shared prefixes (RAG, few-shot, system prompts > 512 tok)SGLangRadixAttention: up to 6.4× more throughput vs a baseline without prefix caching
Maximum throughput on NVIDIA, no portability, team with TRT experienceTRT-LLMFused kernels + native FP8: ITL 9–12 ms vs 18–22 ms for vLLM on the same hardware
Multi-node (> 8 GPUs), mixed prefill-intensive/decode-intensive trafficDynamo + SGLangDisaggregated P/D: up to 7× additional throughput on Blackwell; 2× TTFT with KV-aware routing
AMD ROCm or Intel Gaudi hardwarevLLMThe only SOTA engine with stable non-NVIDIA support
Structured output + high concurrencySGLangCompressed FSM: guided decode with no appreciable overhead
Stable dynamic multi-LoRA in productionvLLM or SGLangTRT-LLM multi-LoRA still in beta (Jun 2026)
Hugging Face ecosystem, models < 13BHF TGI v3Direct HF Hub integration; competitive latency on small models
Maximum energy efficiency (J/token) on NVIDIATRT-LLMLower-overhead kernels → fewer J/token at iso-throughput

Quantisation: effect on throughput and quality

The four main options in order of decreasing speed and increasing quality:

FormatRelative throughput (H100)Quality degradation (perplexity)Engines with stable support
NVFP4 / MXFP4~2.2× vs FP161–3 % on MMLUTRT-LLM (Blackwell), vLLM (experimental)
FP8 (W8A8)~1.7× vs FP16< 1 % on MMLUvLLM, SGLang, TRT-LLM
INT4 AWQ~1.5× vs FP161–2 % on MMLUvLLM, SGLang, TRT-LLM
GPTQ (INT4)~1.4× vs FP161–3 % on MMLUvLLM, SGLang
FP16 (baseline)1.0×0 %All

FP8 is the de facto standard on Hopper for production: 1.7× throughput with degradation below 1 %. The article on quantisation in depth develops the quality/speed trade-off by format and model architecture.


Disaggregated serving: when the overhead is worth it

Separating prefill/decode into independent pools introduces transfer latency for KV tensors between nodes (NIXL over NVLink or InfiniBand). The overhead pays off when:

ConditionEffect of disaggregated serving
Mean ISL > 1,024 tokensPrefill dominates; separate pools stop it blocking decode
Prefill/decode ratio > 3:1 in timeThe decode pool sits idle waiting for prefill
Mixed traffic (prefill burst + decode queue)Independent scaling of each pool by SLA
< 512 tokens ISL, unique promptsTransfer overhead exceeds the benefit; an aggregated engine is enough

Dynamo quantifies the break-even point: disaggregated serving pays off when the transfer time for KV tensors (a function of ISL and NVLink/IB bandwidth) is lower than the time the decode worker would spend waiting for the prefill worker in aggregated mode. On 4×H100 with an ISL of 512 tok, break-even occurs at a prefill/decode ratio > 2.5:1. The article on disaggregated serving develops the full formula.


MLPerf Inference v5.1: cross-vendor reference figures

MLPerf Inference v5.1 (September 2025) is the standard for cross-vendor comparability. Server scenario (Llama-3.1-70B, tokens/s):

SubmitterHardwareScenarioThroughput (tok/s)
Red Hat (vLLM)1×H100 80 GBServer5,103
Red Hat (vLLM)1×L40SServer1,207
NVIDIA (TRT-LLM)8×H100 SXMServer~52,000 (estimated)

The MLPerf figures are not directly comparable with the internal benchmarks above (a different harness, MLPerf’s Server scenario with a Poisson distribution and fixed SLOs). They are useful for comparing vendors under the same rules; not for sizing a specific case. For that, run your own sweep with AIPerf/GuideLLM against the target endpoint.


Variables the benchmark does not capture

Omitted variableEffect in production
Network latency (gateway, load balancer)Can add 20–100 ms to the TTFT measured on the server
Engine compilation time (TRT-LLM)Hours per model×precision×hardware; penalises cold starts and CI
Weight loading time on the GPURelevant in autoscaling; ModelExpress (Dynamo) cuts it 7×
Operational cost of the system (Dynamo vs a simple engine)Dynamo requires etcd/NATS, a Rust runtime, a more specialised team
Response qualityPerformance does not imply quality; measure with lm-evaluation-harness (article B7)
Energy (J/token)Does not come out of a throughput benchmark; requires DCGM running alongside

Sources