Picking the model is the easy part. The harder call is what serves it. Three open engines dominate self-hosted LLM inference right now: vLLM, NVIDIA's TensorRT-LLM, and SGLang. All three speak an OpenAI-compatible API, all three batch requests continuously, and all three will happily saturate an H100. They get there in very different ways, and those differences decide which one fits your deployment far more than any single headline throughput number does.
This guide walks through how each engine actually works, what the published comparisons do and do not tell you, how to run each one in a container, and a decision table for picking one. We have deliberately not printed a benchmark table of our own. Inference throughput swings with model, precision, prompt length, output length, concurrency and engine version, so a number measured on someone else's setup is a weak guide to yours. Where a figure from another team's published test is useful for scale, we name that team as the source.
TL;DR: Start with vLLM if you want the widest model support and the shortest path from "container pulled" to "serving traffic". Reach for TensorRT-LLM when one model will sit in production for months on NVIDIA hardware and you are willing to run a compile step to squeeze out the last slice of throughput and latency. Pick SGLang when your requests share long prefixes (a fixed system prompt, few-shot examples, retrieved documents, multi-turn chat), because its RadixAttention cache reuses that shared work across requests. Whatever you pick, benchmark it on your own model and traffic shape before sizing a fleet.
TL;DR: the three engines at a glance
| Feature | vLLM | TensorRT-LLM | SGLang |
|---|---|---|---|
| Focus | General-purpose, high-throughput serving for as many models as possible | Maximum efficiency on NVIDIA GPUs for a known, stable model | Fast serving for structured, prefix-heavy and agent-style workloads |
| Architecture | PagedAttention KV cache plus continuous batching in a PyTorch runtime | Ahead-of-time compiled engine with fused CUDA kernels, plus a newer PyTorch backend | RadixAttention prefix cache plus a zero-overhead scheduler in a PyTorch runtime |
| Performance character | Strong, predictable throughput across a wide range of loads | Usually the highest ceiling on NVIDIA hardware once the engine is built | Close to vLLM on unique prompts, pulls ahead when prefixes are shared |
| Model support | Broadest of the three, loads most Hugging Face architectures directly | Major open families, often via a conversion or quantization step | Broad and growing fast, strong on new open releases |
| Ecosystem fit | Open source, huge community, default in many platforms | NVIDIA stack: Triton Inference Server, NeMo, NIM, Dynamo | Open source, popular with teams building agents and structured output pipelines |
| Hardware | NVIDIA, AMD ROCm and several other backends | NVIDIA only | NVIDIA and AMD ROCm, plus other accelerators |
| Ease of use | Easiest: one container, one command | Hardest on the compiled path, much easier on the PyTorch backend | Easy: one container, one command |
The short version:
- vLLM if you want flexibility, fast model swaps and the least operational friction.
- TensorRT-LLM if one model is staying put for a long time and throughput per GPU is the metric you are paid on.
- SGLang if your traffic repeats the same prefix across many requests: chatbots, RAG pipelines, agents and multi-turn sessions.
How to set up a fair comparison
Most "engine X is faster" claims fall apart once you look at how the test was run. Before you trust anyone's numbers, including a test you run yourself, check that these variables are held constant across all three engines.
Hardware
Use the same GPU model, the same count and the same host for every engine. An H100 SXM and an H100 PCIe are not the same card: the SXM part has higher memory bandwidth and NVLink, and decode speed is largely a memory-bandwidth problem (see why bandwidth decides inference speed for the mechanism). Driver and CUDA versions matter too, because each engine's container is built against a specific CUDA release and each CUDA release sets a minimum driver version. A mismatch rarely fails politely; it usually shows up as a confusing error at build or load time. Check nvidia-smi on the box before you pull anything.
If you are renting for the test, an H100 is the reference card most published comparisons use, so your results will be easier to compare against theirs. For larger models or long-context work where the KV cache outgrows 80GB, an H200 gives you 141GB on the same Hopper architecture.
Model
Serve the exact same checkpoint at the exact same precision in every engine. FP8 on Hopper is the common choice for a 70B-class model on a single 80GB card, because it roughly halves the weight footprint compared with FP16 and Hopper has hardware FP8 support. Each engine reaches FP8 differently, which is itself part of the comparison: vLLM and SGLang can quantize on load with a single flag, while the classic TensorRT-LLM path quantizes the weights into a checkpoint first and compiles an engine from that. If one engine runs FP8 and another runs FP16, you are comparing precisions, not engines.
Benchmark methodology
A useful methodology looks like this:
- A fixed prompt set with realistic input and output lengths, and a fixed random seed so reruns are comparable.
- Several concurrency levels, for example 1, 10, 50 and 100 simultaneous requests. Single-stream behavior and heavily batched behavior are different regimes, and engines rank differently across them.
- A warm-up period before measurement, so the first-request overheads (CUDA graph capture, cache allocation, JIT work) do not pollute the steady-state numbers.
- Separate metrics for separate questions: output tokens per second for capacity, time to first token (TTFT) at p50 and p95 for responsiveness, and peak VRAM for headroom.
- An explicit statement about prefix sharing. If every prompt is unique, SGLang's biggest advantage is switched off. If prompts share a long system prompt, it is switched on. Neither setup is wrong, but they answer different questions.
Each project ships its own benchmarking tools (vLLM has vllm bench serve, SGLang has sglang.bench_serving, and TensorRT-LLM has trtllm-bench), and they are a reasonable starting point. For a cross-engine comparison, drive all three from the same client so the load generator is not one of the variables.
What the published benchmarks measure
Rather than invent a table, here is what each metric tells you, what the architecture predicts, and where a third-party number exists, who published it.
Throughput (output tokens per second)
Throughput is how many tokens the engine produces per second across all concurrent requests. It is the number that decides how many GPUs you need for a given traffic level, so it maps most directly onto cost.
The architectural prediction is straightforward, and it is what published third-party comparisons tend to find: a compiled engine with fused kernels tuned for one GPU and one shape range has the highest ceiling, so TensorRT-LLM tends to lead on raw throughput once built, with SGLang landing between it and vLLM on unique-prompt workloads. Spheron's published H100 comparison is one example that follows this pattern, serving Llama 3.3 70B at FP8 on a single H100. But that is one team's run on one model with one set of engine versions on one day; the exact gap moves with every release of every engine, so treat any single published number, including that one, as a snapshot rather than a constant worth designing around.
The more important point is that the spread between the three engines on a unique-prompt workload is usually modest compared with the spread you get from tuning any one of them (batch limits, memory fraction, chunked prefill, speculative decoding) or from changing the workload itself.
Time to first token (TTFT)
TTFT is how long a user waits between sending a request and seeing the first token. It is dominated by the prefill phase, where the engine processes the whole prompt before generating anything, plus any time the request spends queued behind others. For chat and interactive tools, p95 TTFT is often the metric users actually feel.
Two architectural facts drive TTFT differences. First, tighter kernels make prefill faster, which favors TensorRT-LLM on raw compute. Second, skipping prefill altogether is faster than any kernel, and that is SGLang's trick: if the prefix is already in the radix cache, those tokens do not need to be recomputed. On a workload with long shared prefixes, that can change the TTFT ranking entirely. vLLM has automatic prefix caching too (on by default in its current V1 engine), so the question for vLLM versus SGLang is less "does it cache" and more how well each engine's cache structure matches your sharing pattern.
Spheron's run, which used unique prompts and so kept prefix reuse out of the picture, reported TensorRT-LLM with the lowest p50 and p95 TTFT at every concurrency level and SGLang between the other two.
Peak VRAM usage
A 70B model at FP8 takes roughly 70GB for weights alone, which leaves only a few gigabytes of an 80GB card for the KV cache, activations and the engine's own buffers. In that situation, the three engines end up within a few gigabytes of each other at peak, because all three are designed to fill the memory you give them with KV cache.
That is worth internalizing: in vLLM you set --gpu-memory-utilization, in SGLang --mem-fraction-static, and TensorRT-LLM has its own KV cache memory fraction. These knobs, along with maximum context length, decide how many concurrent sequences fit far more than the choice of engine does. If you are VRAM-bound, tune context length and memory fraction first, or move up to a card with more memory. For the sizing math, see our GPU guide for LLM inference.
Cold start time
Cold start is where the engines differ most sharply, and it is the one difference that can rule an engine out on day one.
vLLM and SGLang load Hugging Face weights directly, so their cold start is mostly the time to read the weights from disk (or download them) and capture CUDA graphs. That typically lands in the range of a minute or two for a large model on local NVMe. In Spheron's run, vLLM and SGLang each reached their first served request in about a minute.
The classic TensorRT-LLM path adds an ahead-of-time compile. You quantize the checkpoint, build an engine for a specific GPU and a declared range of batch sizes and sequence lengths, then serve that engine. The build is a real one-time cost, commonly tens of minutes for a large model. In Spheron's published H100 benchmark, compiling the 70B engine took roughly 28 minutes. Once built, the engine is saved to disk and later starts reuse it, so the compile is paid per model version and per hardware target, not per restart.
That tradeoff is fine for a model that changes quarterly. It hurts when you scale from zero on demand, run blue-green deploys with fresh model versions, or iterate on fine-tunes daily. TensorRT-LLM's answer is its PyTorch backend, which became the default in the 1.x line and loads Hugging Face weights directly without a separate engine build. You give up some of the compiled path's peak performance in exchange for a startup that looks much more like vLLM's.
vLLM
vLLM came out of UC Berkeley's Sky Computing Lab and is now the most widely deployed open inference engine. Its core idea is PagedAttention: manage the KV cache the way an operating system manages virtual memory. Instead of reserving one large contiguous block per request sized for the maximum possible output, vLLM splits the KV cache into small fixed-size blocks and maps each sequence onto whichever blocks are free, allocating more only as the sequence grows. Almost none of the memory is wasted on space a request never uses, so more requests fit on the same GPU at once.
The second pillar is continuous batching. A static batcher waits for a batch to fill, runs it to completion, then starts the next one, which leaves the GPU idle while the slowest sequence finishes. vLLM instead schedules at the iteration level: finished sequences leave the batch after any step and new ones join, so the GPU stays busy under bursty, uneven traffic without you writing any batching logic.
Running it is a single container. The image serves an OpenAI-compatible API, and FP8 on Hopper is one flag:
docker run --gpus all --ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e HF_TOKEN=your_hf_token \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.3-70B-Instruct \
--quantization fp8 \
--max-model-len 8192 \
--gpu-memory-utilization 0.92 \
--host 0.0.0.0 \
--port 8000
Mounting the Hugging Face cache means a restart does not re-download the weights. Pin a specific image tag instead of latest once you move past experimenting, so an upstream release cannot change behavior under you.
Strengths. The widest model coverage of the three: most text-generation architectures on Hugging Face load directly, including dense models, mixture-of-experts families and a long list of multimodal models. No compile step. An OpenAI-compatible server out of the box. Tensor and pipeline parallelism for multi-GPU serving, automatic prefix caching, speculative decoding, structured output, LoRA adapter serving, and support for AMD ROCm and other hardware backends beyond NVIDIA. It also has the largest community and the most third-party documentation, which matters the first time something breaks at 2am.
Limitations. On NVIDIA hardware, a well-built TensorRT-LLM engine usually has a somewhat higher ceiling at high concurrency. And while vLLM does cache shared prefixes, workloads built entirely around shared prefixes may do better on SGLang. Getting peak numbers out of vLLM also takes some tuning (batch limits, memory fraction, chunked prefill), which the defaults do not always get right for your shape.
TensorRT-LLM
TensorRT-LLM is NVIDIA's inference library for large language models, built on top of TensorRT, its deep-learning compiler. The philosophy is the opposite of a general-purpose runtime. Instead of executing the model through PyTorch operators at request time, the classic path compiles the model ahead of time into an engine: a binary containing a graph of fused CUDA kernels chosen and tuned for one GPU architecture and a declared envelope of batch sizes and sequence lengths. Because the compiler knows the hardware and the shapes in advance, it can fuse operations, pick the fastest kernel variants and lean hard on Tensor Cores and FP8.
Under the hood it also has the serving features you would expect: in-flight batching (NVIDIA's name for continuous batching), a paged KV cache, KV cache reuse, speculative decoding and a wide set of quantization formats including FP8 and INT4 variants. It plugs into the rest of NVIDIA's stack: Triton Inference Server, NeMo, NIM containers and Dynamo for multi-node orchestration.
The classic compiled path is two steps plus a serve step. The exact script paths shift between releases, so check the TensorRT-LLM docs for your version, but the shape looks like this:
# Pick a current release tag from the NGC catalog
TRTLLM_IMAGE=nvcr.io/nvidia/tensorrt-llm/release:<tag>
# Step 1: quantize the Hugging Face weights into an FP8 checkpoint
docker run --gpus all --ipc=host \
-v /data/models:/models -v /data/engines:/engines \
$TRTLLM_IMAGE \
python examples/quantization/quantize.py \
--model_dir /models/Llama-3.3-70B-Instruct \
--dtype float16 \
--qformat fp8 \
--kv_cache_dtype fp8 \
--output_dir /engines/llama70b-fp8-ckpt
# Step 2: compile the engine (the slow, one-time step)
docker run --gpus all --ipc=host \
-v /data/engines:/engines \
$TRTLLM_IMAGE \
trtllm-build \
--checkpoint_dir /engines/llama70b-fp8-ckpt \
--output_dir /engines/llama70b-engine \
--max_batch_size 128 \
--max_input_len 8192 \
--max_seq_len 10240
# Step 3: serve the compiled engine behind an OpenAI-compatible API
docker run --gpus all --ipc=host -p 8000:8000 \
-v /data/engines:/engines \
$TRTLLM_IMAGE \
trtllm-serve /engines/llama70b-engine --host 0.0.0.0 --port 8000
Notice what the build flags do: --max_batch_size, --max_input_len and --max_seq_len are baked into the engine. If your traffic later needs longer contexts or bigger batches than you declared, you rebuild. The engine is also tied to the GPU architecture it was built on, so an engine built on an H100 is not the engine you ship to an L40S.
If you want to skip the compile, the PyTorch backend serves a Hugging Face model directly:
docker run --gpus all --ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e HF_TOKEN=your_hf_token \
$TRTLLM_IMAGE \
trtllm-serve meta-llama/Llama-3.3-70B-Instruct --host 0.0.0.0 --port 8000
Strengths. Usually the highest throughput and lowest latency ceiling on NVIDIA GPUs once the engine is built. First-class support for NVIDIA's newest hardware features and quantization formats, often before the other engines. Deep integration with the NVIDIA enterprise stack, which matters if you already run Triton or buy NVIDIA AI Enterprise support. The PyTorch backend gives you a vLLM-like path when you need fast iteration.
Limitations. NVIDIA only, so no AMD or other accelerators. The compiled path is the most complex deployment pipeline of the three: a one-time build per model version, per GPU type and per shape envelope, with driver and CUDA version requirements that need to line up. Model support is narrower than vLLM's on the compiled path, and brand-new architectures can take longer to land. The team maintaining the pipeline needs more specialist knowledge.
SGLang
SGLang started at LMSYS (the group behind Chatbot Arena) and has grown into a production engine used for some of the largest open models. Its signature feature is RadixAttention, a different way of thinking about the KV cache.
Every request's prompt is a sequence of tokens, and many requests in real systems begin with the same tokens: the same system prompt, the same few-shot examples, the same retrieved document, or the same conversation history followed by one new user turn. SGLang keeps computed KV cache entries in a radix tree keyed by token sequence. When a new request arrives, the engine walks the tree to find the longest prefix it has already computed, reuses that cached state, and only runs prefill on the tokens that are actually new. Cached branches are evicted least-recently-used when memory runs short.
The effect is that a 2,000-token system prompt shared by every request gets computed once instead of once per request. That cuts both TTFT and total GPU work. The benefit is conditional, though: it only exists when prefixes are genuinely shared. On a workload of entirely unique prompts, RadixAttention has nothing to reuse and SGLang behaves like a well-optimized conventional engine.
SGLang also ships a zero-overhead batch scheduler, a fast structured output engine for constrained generation (JSON schemas, regex, grammars), speculative decoding, and strong multi-GPU support including data, tensor and expert parallelism for large mixture-of-experts models.
docker run --gpus all --ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e HF_TOKEN=your_hf_token \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server \
--model-path meta-llama/Llama-3.3-70B-Instruct \
--quantization fp8 \
--context-length 8192 \
--mem-fraction-static 0.9 \
--host 0.0.0.0 \
--port 8000
SGLang's own default port is 30000; the command above sets 8000 so all three engines in this guide answer on the same port.
Strengths. The best fit for prefix-heavy traffic: chatbots with long system prompts, RAG pipelines that reuse context, agents that call the model many times with the same scaffolding, and multi-turn chat. Fast cold start with no compile step. Excellent structured output support. Quick to adopt new open model releases, and strong on very large MoE models. Runs on AMD ROCm as well as NVIDIA.
Limitations. On unique-prompt workloads the headline advantage disappears and it lands roughly level with vLLM. The community and ecosystem are smaller than vLLM's, so there is less third-party material when you hit an edge case. Release cadence is fast, which means new capability but also more flags and defaults that shift between versions.
SGLang vs vLLM: the choice most teams actually make
For a lot of teams, TensorRT-LLM's compiled pipeline is off the table before benchmarks even come up: they swap models too often, they want to scale from zero, or they do not want to maintain a build step. That leaves vLLM versus SGLang, and on paper they look very similar. Both are open source, both load Hugging Face weights directly, both start in about a minute, both expose the same API shape, and on unique prompts they tend to finish close together.
So the deciding factor is your workload shape, not either engine's headline number. The practical test is to measure your prefix overlap. Log a sample of real requests, tokenize them, and check how much of each prompt is a prefix already seen in other requests.
- High prefix overlap (every request carries the same long system prompt, or RAG documents are reused across many queries, or users hold long multi-turn conversations): SGLang's radix cache is built for exactly this and is likely to win on TTFT.
- Low prefix overlap (mostly unique prompts, short system prompts, many different models): vLLM's broader model support, bigger community and simpler operations make it the safer default. Its automatic prefix caching still captures a good share of the simple cases, such as an identical system prompt at the start of every request.
Spheron's write-up offers a rule of thumb of roughly 60% shared-prefix traffic as the point where SGLang becomes the better pick. That threshold comes from their testing, not ours, so treat it as a starting hypothesis to check with your own traffic rather than a fixed line.
The good news is that the switching cost is low. Because both serve the same OpenAI-compatible API, you can run each against a replay of your real traffic on the same rented GPU for an afternoon and let the numbers decide.
vLLM vs TensorRT-LLM: side by side
If SGLang is not in the running and the question is specifically vLLM or TensorRT-LLM, it comes down to five dimensions.
1. Performance
vLLM delivers strong throughput and latency across a wide range of batch sizes and context lengths with minimal configuration. TensorRT-LLM's compiled engines usually push NVIDIA hardware further, thanks to kernel fusion and shape-specific tuning, so for absolute peak numbers on a fixed model it tends to win. The gap is real but not enormous, and it narrows when you use TensorRT-LLM's PyTorch backend instead of a compiled engine.
2. Model support
vLLM loads a very broad range of Hugging Face architectures directly. TensorRT-LLM covers the major open families, but the compiled path often requires converting or quantizing weights into its own checkpoint format first, and new architectures can take longer to be supported.
3. Developer experience
vLLM is one command and you are serving. TensorRT-LLM's compiled path has a steeper learning curve: build flags, shape envelopes, version alignment and rebuilds when anything changes. Once configured, it runs well, but someone on the team has to own that pipeline.
4. Hardware
vLLM runs on most CUDA GPUs from consumer cards up to datacenter parts, and also on AMD ROCm and other backends. TensorRT-LLM is NVIDIA only and is most at home on datacenter GPUs such as the A100, H100, H200 and L40S, with the newest features landing first on the newest architectures.
5. Ecosystem fit
vLLM is open-source-first and slots into almost any stack: Kubernetes operators, Ray Serve, LangChain, LiteLLM and most managed inference platforms use it as a backend. TensorRT-LLM is the natural choice if you are already invested in NVIDIA's AI software stack (Triton, NeMo, NIM) or buy enterprise support from NVIDIA.
When to use each engine
| Condition | Recommended engine |
|---|---|
| You need to serve many different models, or swap models often | vLLM |
| One model stays in long-term production and throughput is paramount | TensorRT-LLM |
| Your requests share system prompts, few-shot examples or RAG context | SGLang |
| You need an instance online within a couple of minutes from cold | vLLM, SGLang, or TensorRT-LLM's PyTorch backend |
| You want the highest ceiling at very high concurrency on NVIDIA | TensorRT-LLM |
| You are experimenting, prototyping or evaluating fine-tunes | vLLM |
| Your team has limited DevOps or MLOps capacity | vLLM |
| You run multi-turn conversations or agent loops at scale | SGLang |
| You need heavy structured output (JSON schema, regex, grammars) | SGLang or vLLM |
| You run on AMD GPUs as well as NVIDIA | vLLM or SGLang |
| You already run Triton Inference Server or the NVIDIA AI stack | TensorRT-LLM |
For most teams the sensible path is to start on vLLM. It covers the most models, has the best documentation, needs no compile step, and its throughput is competitive for the vast majority of workloads. Move to TensorRT-LLM when a model has stopped changing and the throughput difference, multiplied across your fleet, is worth the build pipeline. Move to SGLang when you measure shared-prefix traffic and see it improve TTFT in a way your users notice.
One more thing worth saying: engine choice is rarely the largest lever you have. Precision (FP8 versus FP16), speculative decoding, context-length limits, batch limits and simply matching the GPU to the model tend to move cost per token more than switching engines. Tune the engine you have before you migrate.
Deploy each engine on Aquanode
All three engines run as plain Docker containers on a single GPU, which is exactly what a rented box is for. The flow is the same whichever engine you pick:
- Pick a GPU. Browse live offers on the marketplace, or go straight to H100 listings for the card most benchmarks target. For a 70B model at FP8, an 80GB card is the floor; for longer contexts or bigger models, look at the H200. Smaller models (7B to 30B class) run comfortably on an L40S or A100. The GPU index shows current pricing across providers side by side.
- Deploy the container. From Pods, launch the engine's image with the GPU attached and expose the serving port.
- Check the GPU and endpoint. Once it is up, confirm the GPU is visible and the model is loaded.
vLLM
# Start the server
docker run --gpus all --ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e HF_TOKEN=your_hf_token \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.3-70B-Instruct \
--quantization fp8 \
--max-model-len 8192 \
--host 0.0.0.0 --port 8000
# Verify the endpoint
curl http://localhost:8000/v1/models
TensorRT-LLM
Either build an engine first with the quantize and trtllm-build steps from the TensorRT-LLM section above (a one-time cost per model version), or serve the Hugging Face checkpoint directly on the PyTorch backend:
# Pick a current release tag from the NGC catalog
TRTLLM_IMAGE=nvcr.io/nvidia/tensorrt-llm/release:<tag>
# Serve a compiled engine
docker run --gpus all --ipc=host -p 8000:8000 \
-v /data/engines:/engines \
$TRTLLM_IMAGE \
trtllm-serve /engines/llama70b-engine --host 0.0.0.0 --port 8000
# Verify
curl http://localhost:8000/v1/models
SGLang
# Start the server
docker run --gpus all --ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e HF_TOKEN=your_hf_token \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server \
--model-path meta-llama/Llama-3.3-70B-Instruct \
--quantization fp8 \
--context-length 8192 \
--host 0.0.0.0 --port 8000
# Verify
curl http://localhost:8000/v1/models
Because all three answer on the same port with the same API, you can run your own bake-off on one box: start one engine, replay a sample of your real prompts at a few concurrency levels, stop it, start the next. An afternoon of that on a single rented GPU tells you more about your workload than any published table, including the ones linked above.
A quick request against any of them looks identical:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.3-70B-Instruct",
"messages": [{"role": "user", "content": "Explain PagedAttention in two sentences."}],
"max_tokens": 128
}'
Frequently asked questions
Is vLLM faster than TensorRT-LLM or SGLang?
Not usually at the very top end on NVIDIA hardware. A compiled TensorRT-LLM engine tends to post the highest throughput and lowest TTFT once built; Spheron's published H100 test, for example, found it ahead of vLLM at every concurrency level it measured, by a margin in the high single digits to low teens of percent. SGLang pulls ahead of both on TTFT when requests share long prefixes, and sits close to vLLM when they do not. vLLM's advantage is elsewhere: the broadest model support and the fastest path from nothing to serving, with no compile step. On your workload, the only reliable answer is to test all three on the same GPU.
How long does TensorRT-LLM engine compilation take?
It depends on model size, precision, the GPU, and the batch and sequence envelope you declare, but for a large model it is commonly tens of minutes. In Spheron's published H100 benchmark, building a 70B FP8 engine took roughly 28 minutes. It is a one-time cost per model version and per GPU type: the engine is saved to disk and reused on later starts. If that does not fit your deployment pipeline, TensorRT-LLM's PyTorch backend serves Hugging Face weights directly without a build.
What is SGLang's RadixAttention, and when does it help?
RadixAttention stores computed KV cache entries in a radix tree keyed by token sequence, so when a new request starts with tokens the engine has already processed, it reuses that cached work and only computes the new part. It helps when prefixes are genuinely shared: chatbots with a long fixed system prompt, RAG pipelines that reuse the same documents, few-shot prompting, agent loops and multi-turn conversations. On a workload of entirely unique prompts, there is nothing to reuse, and the benefit mostly disappears.
Can I switch inference engines without changing my API calls?
Yes, for the common endpoints. All three expose an OpenAI-compatible HTTP API with /v1/chat/completions and /v1/completions, so application code that talks to one generally works against the others. What changes is the container image, the launch command and the engine-specific flags. Engine-specific extensions (extra sampling parameters, structured output options) can differ in naming, so test any non-standard fields you rely on.
Which inference engine is best for production at scale?
For most teams, vLLM is the right default: widest model support, the largest community, no compile step, and throughput that holds up across a wide range of loads. Choose TensorRT-LLM when a single model is fixed in production on NVIDIA GPUs and you need the highest throughput or lowest tail latency, and you are prepared to maintain a build pipeline. Choose SGLang when your traffic is dominated by shared prefixes (chat, RAG, agents) and TTFT is the metric your users feel.
Whichever engine wins your bake-off, it only needs a GPU and a container to run. Rent an H100 on Aquanode or pick any card from the marketplace, deploy the engine's image from Pods, and test it against your own traffic today.