SGLang vs vLLM: High-Concurrency Inference Speed & KV-Cache Benchmark

OpsNexusAI Engineering •
10 min read

Overview

Serving Large Language Models at scale requires maximizing GPU utilization while minimizing Time-To-First-Token (TTFT) and Inter-Token Latency (ITL). While vLLM popularized PagedAttention for memory allocation, SGLang introduces RadixAttention—a runtime algorithm designed to reuse KV-caches across complex prompt templates and agentic workflows.

This benchmark report compares SGLang and vLLM on NVIDIA RTX 4090 and A100 GPUs across continuous batching, multi-turn chat, and RAG workloads.


Key Architectural Differences

Feature / AlgorithmvLLM (PagedAttention)SGLang (RadixAttention)
KV-Cache ManagementPage-table allocation (PagedAttention)Trie-tree KV reuse (RadixAttention)
Prefix Caching EfficiencyGood for static system promptsExceptional for multi-turn RAG & agents
Speculative DecodingNative supportSupported via Eagle / Medusa
OpenAI API SupportCompleteComplete

Benchmark Results (Llama 3 8B on RTX 4090 24GB)

[ CONCURRENCY STREAM THROUGHPUT (Tokens/Sec) ]
Con-16 Streams:
  vLLM   : █ 820 tok/s
  SGLang : ████ 980 tok/s  (+19.5% faster)

Con-64 Streams (Shared RAG Context):
  vLLM   : █ 1,120 tok/s
  SGLang : ███████ 1,640 tok/s (+46.4% faster via Radix Cache)

Summary Recommendations

  1. Use SGLang when building multi-turn AI agents or RAG pipelines where system prompts and document contexts are repeatedly reused across API requests.
  2. Use vLLM for standard linear chat completions, single-turn API serving, or multi-node tensor parallel clusters.

SGLang vs vLLM Engine Architecture Comparison

Serving complex multi-turn LLM agent prompts or structured JSON outputs requires optimizing request handling speed and token decoding latency.

While vLLM pioneered PagedAttention to manage key-value (KV) memory fragmentation, SGLang introduces RadixAttention—an automatic KV cache reuse mechanism that builds an in-memory radix tree across shared prefix prompts (e.g. system prompts, few-shot code examples, and tools definitions).

+-------------------------------------------------------------------------+
|                  PagedAttention vs RadixAttention                       |
|  +-------------------------------------------------------------------+  |
|  | vLLM (PagedAttention)                                             |  |
|  | [ Block 0 ] -> [ Block 1 ] -> [ Block 2 ] (Fixed KV Page Blocks)   |  |
|  +-------------------------------------------------------------------+  |
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | SGLang (RadixAttention)                                           |  |
|  | Root Tree -> [ System Prompt Node ] ---> [ Few-Shot Examples ]     |  |
|  |                                  ---> [ User Input Variations ]   |  |
|  +-------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+

Step 1: SGLang High-Throughput Docker Deployment Manifest

version: '3.8'

services:
  sglang-server:
    image: lmsysorg/sglang:latest
    container_name: sglang-inference
    restart: always
    runtime: nvidia
    environment:
      - CUDA_VISIBLE_DEVICES=0,1
    ports:
      - "30000:30000"
    ipc: host
    command: >
      python3 -m sglang.launch_server
      --model-path Qwen/Qwen2.5-Coder-32B-Instruct
      --tp 2
      --port 30000
      --host 0.0.0.0
      --mem-fraction-static 0.90
      --schedule-policy lpm

Step 2: Comparative Benchmark Suite Script

Execute parallel load generation using locust or Python asyncio to measure latency and token throughput:

import asyncio
import time
import aiohttp

URL = "http://localhost:30000/generate"
PROMPT = "System: You are an expert Rust backend developer.\nUser: Write a lock-free queue.\nAssistant:"

async def send_request(session, req_id):
    start = time.perf_counter()
    payload = {
        "text": PROMPT,
        "sampling_params": {"temperature": 0.1, "max_new_tokens": 256}
    }
    async with session.post(URL, json=payload) as resp:
        data = await resp.json()
        latency = time.perf_counter() - start
        return latency

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [send_request(session, i) for i in range(50)]
        latencies = await asyncio.gather(*tasks)
        print(f"Average Latency: {sum(latencies)/len(latencies):.4f} sec")

if __name__ == "__main__":
    asyncio.run(main())

OpsNexusAI Engineering

Verified Lab Publication

OpsNexusAI is a technical laboratory dedicated to sovereign AI infrastructure. Every implementation guide and architectural blueprint published here is tested on physical hardware and isolated networks. Our team specializes in the deployment of private LLMs, network hardening with OPNsense, and enterprise-grade automation patterns.


Join the OpsNexus Brief

Get technical teardowns on sovereign AI architectures delivered to your inbox.