Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cross-engine decision rubric for self-hosting or recommending an LLM serving stack. Picks among vLLM, SGLang, TensorRT-LLM, TGI, llama.cpp, Ollama, and MLX as a function of (hardware × workload × constraint), not "which is fastest". Activates whenever a coder-agent must choose, defend, or migrate a serving runtime.
.claude/skills/agentsope-agentsop-llm-engine-selection/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 308% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 181% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 625% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 221% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 168% | 0% |
> State-of-the-art warning. This skill is dated May 2026. The inference-engine landscape moves in 3–6 month cycles (TGI exited maintenance into deprecation in late 2025; SGLang's RadixAttention regressed vLLM's lead in 2024; TensorRT-LLM dropped its proprietary-engine requirement in 2025; Ollama added concurrent-request support mid-2025). Re-verify before betting a quarter of eng budget on any choice below.
Activate this skill any time a coder-agent must:
Do not activate for:
vllm, sglang, tensorrt-llm, llama-cpp).accelerate, deepspeed, axolotl).Engine choice is a function of (hardware × workload × constraint), not "which is fastest".
There is no global ranking. Every "X beats Y by N%" headline holds only inside an unstated (hardware, batch size, ISL/OSL, model, quantization, concurrency) tuple. Change any axis and the ranking flips.
For GPU-backed, multi-user, open-weights serving, the default is vLLM. It owns the production slot because it is vendor-neutral (NVIDIA/AMD/Intel/TPU/Apple-experimental), supports 200+ architectures including MoE/multimodal, ships an OpenAI-compatible API, and HuggingFace themselves recommend it over their own (now-maintenance-mode) TGI yottalabs.ai 2026; vllm-project README].
You only reach past vLLM when one of three conditions binds:
Throughput-per-GPU, throughput-per-dollar, P50 TTFT, P99 ITL, and developer-time-to-first-request are five different goals, and the engines optimize for different combinations:
| Engine | What it optimizes for | |---|---| | vLLM | Throughput-per-GPU across mixed traffic, model breadth | | SGLang | Throughput when requests share prefix; structured-gen TPS | | TensorRT-LLM | Peak throughput on NVIDIA at saturation; per-token cost at scale | | TGI | Was generic; now mostly a migration source | | llama.cpp | Single-user TPS on CPU/Apple/edge; minimal-deps install | | Ollama | Developer-time-to-first-request (5 min) | | MLX | Apple Silicon throughput and Apple-native dev UX |
Pick by which axis your project is binding on, not by which engine has the most stars.
[Step 0] Define the four-axis constraint vector
├─ Hardware: GPU vendor, count, interconnect (NVLink? PCIe?), VRAM/GPU
├─ Workload: # concurrent users, ISL/OSL distribution, shared-prefix %, structured-out %
├─ Constraint: license, vendor-lock tolerance, eng-days budget, P50/P99 SLA
└─ Model: family (Llama/Qwen/Mixtral/DeepSeek/Mamba/...), size, quantization preference
[Step 1] Eliminate incompatible engines (hard filters)
├─ No NVIDIA GPU? → drop TensorRT-LLM
├─ CPU/Apple/edge only? → drop vLLM (production), TGI, TensorRT-LLM
├─ Need OSS-permissive only? → drop TensorRT-LLM (NVIDIA license)
├─ Mamba / brand-new arch? → check vLLM+SGLang coverage; likely drop others
└─ Multi-LoRA hot-swap? → vLLM (best), TensorRT-LLM (good), SGLang (good); others drop
[Step 2] Map workload to engine strength
├─ Throughput + mixed traffic → vLLM
├─ Shared prefixes (chatbot, agent) → SGLang (≈29% over vLLM on shared-context [n1n.ai 2026])
├─ Structured JSON/regex at scale → SGLang (RadixAttention + state machines)
├─ Peak throughput, NVIDIA-only, big budget → TensorRT-LLM (+30–50% over vLLM [n1n.ai 2026])
├─ Single user, dev laptop → Ollama
├─ CPU/Apple/edge/embedded → llama.cpp / MLX
└─ Multi-tenant SaaS with LoRA fleet → vLLM (multi-LoRA mature) or SGLang
[Step 3] Sanity-check hardware topology
├─ TP requires NVLink (≈900 GB/s) — not PCIe Gen4 (≈32 GB/s, ~28× slower)
├─ PCIe-only box → smaller TP + replicas, or PP, or switch engines
├─ Cross-NUMA across the same node → as bad as PCIe; pin to NUMA-local GPUs
└─ Multi-node → require IB / RoCE, not Ethernet
[Step 4] Benchmark top 2 on YOUR workload
├─ Replay representative ISL/OSL distribution (NOT MMLU prompts)
├─ Measure P50 + P99 TTFT, P50 + P99 ITL, tokens/s/GPU, $/M-tokens
├─ Watch saturation: queue depth, KV occupancy, preemption count
└─ Decide; document the constraint vector that justified the pick
[Step 5] Plan the escape hatch
├─ Note the workload threshold that would force a switch
├─ Keep the OpenAI-compatible API layer so swaps are mechanical
└─ Re-evaluate every 6 months — engines evolve in quarters, not yearsguided_decoding overhead on agent traffic → A/B SGLang.guided_decoding at scale. If staying on vLLM, expect throughput hit on constrained requests; budget for it.Situation: A team standardized on vLLM but their cluster is 4× L40S on PCIe Gen4 (no NVLink). They configure --tensor-parallel-size 4 for Llama-3-70B-FP8 and see throughput collapse — single-replica TPS is ~30% of what the H100×4 benchmark advertises.
Tension:
Resolution:
TP=2 × 2 replicas (each replica uses an NVLink-paired or NUMA-local pair, if any), or use pipeline parallelism PP=4, TP=1. Replicas eliminate the cross-GPU all-reduce on the hot path developers.redhat.com 2026 step-5].Evidence: docs.vllm.ai parallelism_scaling]; developers.redhat.com 2026]; spheron.network 2026].
Situation: An agent platform serves Qwen-2.5-32B-Instruct with ~70% of requests demanding strict JSON schema output (tool-calling, function arguments). On vLLM with guided_decoding, throughput drops ~40% vs unconstrained baseline; P99 TTFT regresses.
Tension:
Resolution:
guided_decoding (xgrammar backend), and re-evaluate next quarter.Evidence: sglang.ai/blog]; n1n.ai 2026]; yottalabs.ai 2026].
Situation: NVIDIA-only cluster (8×H100, NVLink-full), single-tenant, throughput-per-GPU is the dominant cost line. Team has 2 weeks of senior eng time. TensorRT-LLM promises +30–50% throughput n1n.ai 2026] but requires engine build per (model × precision × max-batch × max-seq) tuple.
Tension:
Resolution:
Evidence: n1n.ai 2026]; yottalabs.ai 2026]; spheron.network 2026].
Situation: A small team wants the same engine for local dev on M-series Macs AND production on cloud NVIDIA. They are tempted to standardize on Ollama (since it runs everywhere) or vLLM (since it's the prod default).
Tension:
Resolution:
Evidence: contracollective.com 2026]; yottalabs.ai 2026].
vLLM has ~50k stars, llama.cpp has ~70k, TensorRT-LLM has ~10k. Stars do not predict fit for YOUR workload. A 70-star project may be the only thing that runs your model on your hardware. Pick by the constraint vector (§3 Step 0), not by popularity.
The "X is 5× faster than Y" blog you skimmed had specific (hardware, model, batch, ISL/OSL) parameters. Most blogs do not state them. Treat every comparison as ungeneralizable until you've replicated it with YOUR parameters.
PCIe-only TP. Cross-NUMA all-reduce. Ethernet between nodes for tensor-parallel. Each of these turns a "fastest engine" into a slowest engine. The engine isn't the variable; the interconnect is. Check the topology before blaming the engine spheron.network 2026].
Ollama and llama.cpp can give you a faster first token on a single request than vLLM's cold path. This proves nothing about serving 50 users. Benchmark at YOUR concurrency, not at concurrency=1.
TensorRT-LLM ships under NVIDIA's proprietary license. If your shop forbids non-OSS in the inference path (e.g. air-gapped, regulated, or open-core-only orgs), this is a hard filter — no benchmark matters. Same caveat for any Triton-integrated engine that pulls in NVIDIA-proprietary components.
HuggingFace themselves moved their internal recommendation to vLLM and SGLang; TGI is in maintenance mode yottalabs.ai 2026]. Existing TGI deployments are fine if they meet SLA, but new projects in 2026 should not pick TGI.
Ollama has added concurrent-request support, but its sweet spot is local dev. A production deployment on Ollama at 10+ QPS wastes 80–95% of GPU capacity vs vLLM contracollective.com 2026; aimadetools.com 2026]. Use Ollama for dev, swap to vLLM for prod.
This skill is correct when:
This skill is not the right tool when:
vllm, sglang, tensorrt-llm, llama-cpp skills.| Engine | Best for | Hardware | License | One-line strength | One-line weakness | |---|---|---|---|---|---| | vLLM | Production GPU serving, mixed traffic, open weights | NVIDIA / AMD / Intel / TPU / Apple (exp.) | Apache 2.0 | Vendor-neutral, broadest model coverage, HF-blessed default | Not the fastest in any single niche | | SGLang | Shared-prefix workloads, agents, RAG, structured generation | NVIDIA / AMD | Apache 2.0 | RadixAttention prefix tree + native state machines; ~29% over vLLM on shared-context | Smaller model coverage; smaller ecosystem | | TensorRT-LLM | Peak NVIDIA throughput at saturation | NVIDIA only | NVIDIA proprietary | +30–50% over vLLM in NVIDIA-only deployments | Vendor lock-in; 1–2 weeks setup; per-config engine rebuild | | TGI | Existing HF-stack deployments | NVIDIA / AMD | HFOIL (Apache-restricted) | Was the HF default | Maintenance mode; HF now recommends vLLM/SGLang | | llama.cpp | CPU / Apple Silicon / edge / single user / GGUF | x86 / ARM / Apple / consumer GPU / CUDA / Vulkan | MIT | Runs anywhere; minimal deps; GGUF ecosystem | Per-request overhead doesn't scale to many concurrent users | | Ollama | Local dev, prototyping, model switching | Wraps llama.cpp | MIT | 5-minute install; best dev UX | Concurrent throughput is poor vs vLLM-class engines | | MLX / vllm-mlx | Apple Silicon native | M-series only | MIT | Apple's first-party path; best Mac throughput | Mac-only; smaller ecosystem |
All numbers assume the engine's preferred topology (NVLink for vLLM/TRT-LLM, etc.). Cross-topology comparisons are meaningless.
GPU-backed multi-user production?
├─ Yes
│ ├─ Heavy shared prefixes or structured-out >30%? → SGLang
│ ├─ NVIDIA-locked + max throughput + 2wk budget? → TensorRT-LLM
│ ├─ Multi-LoRA SaaS / multi-tenant? → vLLM (or SGLang)
│ └─ Default / mixed traffic / new model → vLLM
└─ No
├─ Dev laptop / 5-min setup? → Ollama
├─ CPU / Apple / edge / single user? → llama.cpp (or MLX on Mac)
├─ Apple production server? → MLX or llama.cpp Metal
└─ Existing TGI that works? → stay; plan migration to vLLMLocal dev → Ollama
Prod benchmark → vLLM (default)
If prefix-heavy → A/B with SGLang
If NVIDIA-only + → A/B with TensorRT-LLM
eng budget
Edge / on-device → llama.cpp + GGUF
Apple-native → MLXvLLM occupies the default production slot for open-weights LLM serving in 2026; everything else is a workload-justified deviation.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 17,365 | 20,777 | +20% | 1 | 1 | 0% | 2,991 | 10,149 | +239% | 0 | 0 | — |
case-02 | fail→pass | 12,072 | 11,039 | -9% | 1 | 1 | 0% | 2,167 | 8,845 | +308% | 0 | 0 | — |
case-03 | fail→pass | 17,607 | 8,922 | -49% | 1 | 1 | 0% | 2,996 | 8,429 | +181% | 0 | 0 | — |
case-04 | pass→pass | 23,886 | 20,614 | -14% | 1 | 1 | 0% | 3,970 | 10,626 | +168% | 0 | 0 | — |
case-05 | pass→pass | 43,805 | 14,655 | -67% | 1 | 1 | 0% | 3,800 | 9,282 | +144% | 0 | 0 | — |
case-06 | fail→pass | 32,652 | 12,962 | -60% | 1 | 1 | 0% | 1,248 | 9,053 | +625% | 0 | 0 | — |
case-07 | pass→pass | 19,088 | 12,665 | -34% | 1 | 1 | 0% | 2,880 | 8,977 | +212% | 0 | 0 | — |
case-08 | pass→pass | 17,899 | 16,263 | -9% | 1 | 1 | 0% | 2,745 | 9,743 | +255% | 0 | 0 | — |
case-09 | pass→pass | 8,568 | 7,883 | -8% | 1 | 1 | 0% | 1,315 | 8,305 | +532% | 0 | 0 | — |
case-10 | pass→pass | 14,152 | 12,177 | -14% | 1 | 1 | 0% | 2,292 | 8,966 | +291% | 0 | 0 | — |
case-11 | pass→pass | 14,258 | 15,222 | +7% | 1 | 1 | 0% | 2,333 | 9,573 | +310% | 0 | 0 | — |
case-12 | pass→pass | 13,876 | 14,584 | +5% | 1 | 1 | 0% | 2,223 | 9,350 | +321% | 0 | 0 | — |
case-13 | pass→pass | 17,625 | 12,604 | -28% | 1 | 1 | 0% | 2,883 | 9,090 | +215% | 0 | 0 | — |
case-14 | pass→pass | 6,647 | 6,339 | -5% | 1 | 1 | 0% | 1,098 | 8,096 | +637% | 0 | 0 | — |
case-15 | pass→pass | 18,470 | 14,311 | -23% | 1 | 1 | 0% | 2,807 | 9,119 | +225% | 0 | 0 | — |
case-16 | pass→pass | 15,669 | 16,446 | +5% | 1 | 1 | 0% | 2,604 | 9,797 | +276% | 0 | 0 | — |
case-17 | pass→pass | 15,911 | 16,352 | +3% | 1 | 1 | 0% | 2,576 | 9,534 | +270% | 0 | 0 | — |
case-18 | fail→pass | 19,766 | 19,363 | -2% | 1 | 1 | 0% | 3,158 | 10,148 | +221% | 0 | 0 | — |
case-19 | pass→pass | 17,966 | 11,977 | -33% | 1 | 1 | 0% | 2,727 | 8,879 | +226% | 0 | 0 | — |
case-20 | pass→pass | 16,259 | 11,436 | -30% | 1 | 1 | 0% | 2,666 | 8,807 | +230% | 0 | 0 | — |
case-21 | pass→pass | 9,924 | 10,647 | +7% | 1 | 1 | 0% | 1,686 | 8,965 | +432% | 0 | 0 | — |
case-22 | fail→fail | 7,752 | 7,686 | -1% | 1 | 1 | 0% | 1,227 | 8,417 | +586% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +18 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.