Deploy SGLang with Docker on Linux: Faster LLM Inference Using RadixAttention

AI tutorial - IT technology blog
AI tutorial - IT technology blog

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-smi returns 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-static to 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:30000 to -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.

Share: