SGLang vs vLLM: Which One Should You Run?
Self-hosting LLMs? You’ve almost certainly already tried vLLM. It’s the default serving framework for most teams — mature, well-documented, and reliable out of the box. SGLang, though, has been quietly gaining ground, particularly for workloads involving complex prompt structures or multi-turn conversations.
The core difference is how each framework handles the KV cache. vLLM uses PagedAttention, managing GPU memory in fixed-size blocks. It’s a big improvement over naive implementations. But it hits a wall when many requests share the same prefix. SGLang’s RadixAttention treats the KV cache as a radix tree. Two requests sharing the same system prompt? That prefix is computed once and reused — no duplication, no wasted compute.
For a single one-shot query, you won’t notice the difference. But run a chatbot where every request starts with the same 500-token system prompt, and RadixAttention starts paying dividends. Same story for coding assistants that prepend hundreds of tokens of codebase context on every call.
Quick comparison:
- vLLM — PagedAttention, large ecosystem, OpenAI-compatible API, excellent throughput for diverse workloads
- SGLang — RadixAttention, faster prefix reuse, native structured output support, growing ecosystem
Pros and Cons
SGLang
- Pro: Significant speedup for shared-prefix workloads (chatbots, agents, RAG pipelines)
- Pro: Built-in structured output support — JSON schema enforcement without bolting on external libraries
- Pro: OpenAI-compatible API, so most client code works without modification
- Pro: Active development with frequent releases
- Con: Smaller community than vLLM
- Con: Docs are improving but still have gaps on edge cases
- Con: Fewer quantization options out of the box
vLLM
- Pro: Battle-tested at production scale
- Pro: Wide model support and quantization options (GPTQ, AWQ, etc.)
- Pro: Larger community and more existing troubleshooting resources
- Con: No prefix caching by default (though it can be enabled)
- Con: Higher TTFT for repeated-prefix workloads
I ran SGLang in production for a customer support chatbot that prepended a 300-token system prompt to every request. TTFT dropped roughly 40% compared to vLLM on identical hardware. Three months in, error rates stayed flat. The results held up.
Recommended Setup
Get these in order before touching any Docker commands:
- Linux host (Ubuntu 22.04 or later recommended)
- NVIDIA GPU with at least 16GB VRAM (24GB+ for 7B+ models at full precision)
- NVIDIA drivers installed and working (
nvidia-smireturns output) - Docker Engine installed
- NVIDIA Container Toolkit installed
- At least 50GB free disk space for model weights
Not sure the NVIDIA Container Toolkit is wired up correctly? Run this quick test:
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
GPU info in the output means you’re good. A permission or driver error means stop here and fix that first — nothing downstream will work until Docker can see your GPU.
One more thing: keep your Hugging Face cache on the host, not inside the container. Mount it as a volume (covered in Step 3) so you don’t re-download weights every time you rebuild the image.
Implementation Guide
Step 1: Pull the SGLang Docker Image
SGLang publishes official images on Docker Hub. Grab the latest stable release:
docker pull lmsysorg/sglang:latest
On CUDA 11.8 instead of 12.x? Check available tags on Docker Hub and pin to a specific version. Don’t use latest in production — it can silently break between releases.
Step 2: Set Up Your Model Directory
Create a directory on the host for model weights, then point the Hugging Face cache at it:
mkdir -p /data/hf-cache
export HF_HOME=/data/hf-cache
Pre-downloading the model before starting the server avoids timeout issues on first launch. Use the Hugging Face CLI:
pip install huggingface-hub
huggingface-cli download meta-llama/Llama-3.1-8B-Instruct \
--local-dir /data/hf-cache/hub/models--meta-llama--Llama-3.1-8B-Instruct
Swap in whatever model you’re deploying. Gated models like Llama need a Hugging Face token — run huggingface-cli login first.
Step 3: Launch the SGLang Server
Here’s the core Docker run command:
docker run -d \
--name sglang-server \
--gpus all \
--shm-size 32g \
-p 30000:30000 \
-v /data/hf-cache:/root/.cache/huggingface \
lmsysorg/sglang:latest \
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 30000 \
--mem-fraction-static 0.85
Three flags that trip people up:
--shm-size 32g— SGLang uses shared memory for inter-process communication. Docker’s default is 64MB. That’s nowhere near enough, and the resulting crashes produce cryptic error messages. Set this to at least 32GB on machines with sufficient RAM.--mem-fraction-static 0.85— Allocates 85% of GPU VRAM to the static KV cache. Leave headroom for model weights and runtime overhead. OOM on startup? Drop this to 0.75.-p 30000:30000— The server listens on port 30000 by default. Change the left side if that port is already taken.
Step 4: Verify the Server is Running
Tail the container logs to confirm the server came up cleanly:
docker logs -f sglang-server
Watch for The server is fired up and ready to roll!. Once it appears, hit the health endpoint:
curl http://localhost:30000/health
A 200 response means the server is alive. Then test an actual inference request:
curl http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"messages": [{"role": "user", "content": "What is RadixAttention?"}],
"max_tokens": 256
}'
Step 5: Use Docker Compose for Easier Management
For anything beyond a one-off test, Docker Compose is the better approach. Create a docker-compose.yml:
services:
sglang:
image: lmsysorg/sglang:latest
container_name: sglang-server
restart: unless-stopped
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
shm_size: 32g
ports:
- "30000:30000"
volumes:
- /data/hf-cache:/root/.cache/huggingface
command: >
python -m sglang.launch_server
--model-path meta-llama/Llama-3.1-8B-Instruct
--host 0.0.0.0
--port 30000
--mem-fraction-static 0.85
Bring it up:
docker compose up -d
The restart: unless-stopped policy handles reboots and crashes automatically. Essential for anything running in production.
Step 6: Connect Your Application
SGLang’s OpenAI-compatible API means existing code using the OpenAI SDK works with exactly one change — the base URL:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:30000/v1",
api_key="none" # SGLang doesn't require an API key by default
)
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain KV cache in one paragraph."}
]
)
print(response.choices[0].message.content)
Troubleshooting Common Issues
A handful of problems show up on almost every first setup:
- OOM on startup — Lower
--mem-fraction-staticto 0.70 or 0.75. If the model still doesn’t fit, you need a bigger GPU or a quantized model variant. - Slow first request — Expected. SGLang compiles CUDA kernels on first run and caches them locally. Subsequent restarts are noticeably faster.
- Port already in use — Change
-p 30000:30000to-p 8080:30000(or any open port on the left side). - Model not found — Verify the volume mount and confirm model files are at
/data/hf-cache. Check with:docker exec -it sglang-server ls /root/.cache/huggingface
SGLang is worth running if your workload involves any prefix reuse — system prompts, RAG context, few-shot examples. The Docker setup is straightforward once the GPU toolkit is sorted, and migrating from vLLM is usually a one-line change.

