vLLM vs SGLang: Real‑World Architecture, KV‑Cache Strategies & Distributed Inference at Scale
Practical guidance for building production‑grade LLM serving pipelines on modern GPU clusters
SEO/AEO Summary
Keywords: vLLM vs SGLang, KV cache offload, NVMe bandwidth, NCCL profiling, tensor‑parallel inference, multi‑node GPU serving, low‑latency LLM inference.
Meta description: A production‑focused deep dive into vLLM and SGLang architectures, KV‑cache pinning techniques, and distributed inference design. Includes concrete bandwidth calculations, NCCN profiling tips, and an operational post‑mortem from large‑scale deployments.
1. Architectural Foundations
Both vLLM (GitHub) and SGLang (GitHub) share a common goal: squeeze the maximum number of concurrent request slots out of a fixed GPU memory budget. Their divergence lies in how they orchestrate the KV (key‑value) cache, schedule attention kernels, and expose parallelism to the host.
vLLM’s “Paged Attention” Engine
vLLM treats the KV cache as a pageable buffer residing in GPU DRAM. When the aggregate token count exceeds the resident capacity, it spills the oldest pages to host memory via pinned CUDA allocations. The spill‑to‑host path is deliberately asynchronous: a dedicated CUDA stream copies 64 MiB pages to a pre‑registered host buffer while the compute stream continues processing new tokens. Because the host buffer is pinned, the PCIe DMA engine can sustain near‑line‑rate throughput, but the practical ceiling is dictated by the PCIe generation and lane count.
Real‑world math: On a server equipped with a PCIe 4.0 x8 link, the theoretical peak is ≈ 16 GB/s per direction, but measured sequential throughput for large, aligned transfers hovers around 7–8 GB/s after accounting for protocol overhead and driver latency. Consequently, a 256 MiB KV spill consumes roughly 30–35 ms of wall‑clock time, which is acceptable for workloads where the average request length stays below 128 tokens.
SGLang’s “Hybrid KV Cache”
SGLang introduces a hybrid cache that keeps the most recent N tokens in GPU memory while allocating a NVMe‑backed memory pool for older context. The pool is accessed through the Linux kernel’s Direct‑IO path, which bypasses the page cache and guarantees deterministic I/O latency. The NVMe device is typically attached via PCIe 4.0 x4, delivering ~3.5 GB/s sequential read/write. SGLang batches KV fetches in 4 MiB chunks to amortize the per‑IO overhead, achieving an effective bandwidth of ≈ 2.8 GB/s in practice.
Because the NVMe path is slower than PCIe‑host RAM, SGLang compensates by pre‑fetching the next KV segment while the current attention kernel runs. This overlap reduces the perceived latency penalty to under 15 ms for a 256 MiB fetch on a 2‑node setup, assuming the compute kernel occupies at least 20 ms of GPU time per batch.
2. KV‑Cache Pinning & Memory Discipline
Why Pinning Matters
Pinned (page‑locked) host memory eliminates the extra copy that the GPU driver would otherwise insert when staging data for DMA. The trade‑off is a reduction in the amount of host RAM available for other processes, but on inference servers the host is typically dedicated to the serving stack, making the sacrifice worthwhile.
Pinning Strategy for vLLM
vLLM allocates a single contiguous pinned buffer sized to 2× the maximum expected spill volume. The buffer is registered once at process start, avoiding repeated cudaHostRegister calls that would otherwise fragment the system’s page tables. The buffer is divided into a ring of 64 MiB slots; each spill writes to the “head” slot while the “tail” slot is reclaimed after the GPU has signaled completion via a CUDA event.
Pinning Strategy for SGLang
SGLang’s hybrid cache leverages O_DIRECT file I/O on a dedicated NVMe namespace. The OS guarantees that the pages are never cached, but the application must align both the file offset and the I/O size to the device’s logical block size (typically 4 KiB). SGLang aligns to 4 MiB boundaries to match the NVMe controller’s internal stripe size, ensuring that each request triggers a single DMA operation rather than a scatter‑gather sequence.
3. Distributed Inference Backbone
Tensor‑Parallelism & NCCL
Both runtimes rely on NVIDIA NCCL (NCCL docs) for collective communication across GPUs. The critical path is the all‑reduce of attention logits, which must complete before the next token can be sampled.
Profiling tip: Use NCCL_DEBUG=INFO together with nvprof or nsys to capture the latency of each collective. In a 8‑GPU DGX‑H100 (NVLink 4‑hop mesh), the all‑reduce latency for a 32 KiB buffer sits at ≈ 8 µs; for a 2‑MiB buffer it rises to ≈ 70 µs. The increase is linear with the number of bytes until the inter‑connect saturates (~200 GB/s per NVLink).
Cross‑Node Scaling
When scaling beyond a single node, the inter‑node link is typically InfiniBand HDR (200 Gbps ≈ 25 GB/s). The effective bandwidth for NCCL’s ring algorithm drops to ≈ 15 GB/s after accounting for protocol overhead. Consequently, a 4‑node, 8‑GPU‑per‑node tensor‑parallel job (total 32 GPUs) experiences an extra ≈ 120 µs all‑reduce latency for a 2‑MiB tensor compared with a single node.
Scheduling & Load Balancing
Both runtimes expose a request‑level scheduler that maps incoming prompts to GPU shards based on current token count. A practical heuristic is to maintain a target occupancy of 70 % of the KV cache per GPU; once a shard exceeds this threshold, new requests are routed to the least‑loaded GPU. This approach smooths the tail latency distribution without requiring a full-fledged load‑balancer.
4. NVMe Bandwidth & KV Offload Economics
Assume a server equipped with a PCIe 4.0 x8 NVMe SSD delivering 7.5 GB/s sequential read. If the KV cache for a 70‑B model (≈ 1.2 GiB per 1 k token context) is offloaded after 2 k tokens, the system must read ≈ 2.4 GiB of KV data for the next request. At 7.5 GB/s, the raw transfer takes ≈ 320 ms; however, by pre‑fetching 512 MiB chunks and overlapping with GPU compute, the perceived latency can be reduced to ≈ 120 ms, which is still a noticeable tail but acceptable for batch‑oriented workloads (e.g., RAG pipelines).
If the same workload runs on a PCIe 5.0 x4 NVMe (≈ 4 GB/s), the raw read halves to ≈ 160 ms, and the overlapped latency drops to ≈ 80 ms. The engineering decision therefore hinges on whether the target service‑level objective tolerates a 100 ms tail spike.
5. Operational Post‑Mortem: Lessons from the Trenches
Asymmetric Peer Groups in Tensor Parallelism
During a multi‑region rollout, we discovered that a subset of GPUs on a single node were wired to a different NVLink topology (four‑way vs. six‑way mesh). NCCL’s default ring algorithm treated the group as symmetric, causing a 30 % slowdown in all‑reduce latency for those peers. The fix was to enable NCCL’s topology‑aware mode (NCCL_ALGO=Tree) and explicitly set NCCL_SOCKET_IFNAME=eth0 for cross‑node traffic.
Cross‑Node NVLink Latency Variability
Our monitoring showed a jitter of ± 15 µs in intra‑node NVLink latency when the host OS scheduled background I/O on the same PCIe root complex. Pinning the inference process to a dedicated CPU NUMA node and disabling irqbalance eliminated the variance, stabilizing the tail latency distribution.
NCCL Trace Debugging
A sporadic deadlock surfaced after a kernel upgrade; the NCCL logs displayed “NCCL WARN: Unexpected abort”. Using nsys we traced the issue to a mismatched CUDA stream priority between the attention kernel (high priority) and the KV spill stream (low priority). The low‑priority stream was starved, causing the CUDA event that signals spill completion to never fire. Raising the spill stream to default priority resolved the deadlock.
KV Cache Pinning Pitfalls
On a server with 256 GiB of DRAM, we allocated a 64 GiB pinned buffer for vLLM. The OS refused to grant the request after a few weeks of uptime because the mlock limit (/proc/sys/vm/overcommit_memory) was set to 2. Adjusting ulimit -l unlimited and setting vm.overcommit_memory=1 restored the ability to pin the full buffer.
6. Putting It All Together – A Reference Deployment Blueprint
| Component | Recommended Config | Rationale |
|---|---|---|
| GPU | NVIDIA H100 (80 GB) × 8 per node | High‑bandwidth NVLink, ample DRAM for on‑GPU KV |
| Inter‑connect | NVLink intra‑node, InfiniBand HDR inter‑node | NCCL achieves sub‑100 µs all‑reduce for 2 MiB tensors |
| KV Offload | PCIe 4.0 x8 NVMe SSD (≥ 7 GB/s) + pinned host RAM (≥ 64 GiB) | Balances cost and latency; pre‑fetch mitigates tail |
| Runtime | vLLM or SGLang (choose based on KV pattern) | vLLM for high‑throughput bursty traffic; SGLang for long‑context RAG |
| Scheduler | Token‑count‑aware per‑GPU queue, target occupancy ≈ 70 % | Keeps tail latency low without over‑provisioning |
| Monitoring | NCCL profiling (NCCL_DEBUG=INFO), GPU utilization (nvidia-smi dmon), I/O latency (iostat -x) |
Early detection of asymmetric topology or I/O stalls |
| Failover | Stateless request routing, checkpoint KV snapshots every 5 min | Enables rapid node replacement without losing context |
7. FAQ
Q1. When should I prefer vLLM over SGLang?
If your workload consists of many short, high‑throughput requests and you have ample host RAM for pinned buffers, vLLM’s paged attention offers lower average latency. Choose SGLang when you routinely need context windows exceeding 8 k tokens, as its NVMe‑backed hybrid cache handles deep histories more gracefully.
Q2. How large can the KV cache be before spilling becomes a bottleneck?
On a PCIe 4.0 x8 link, a continuous spill rate of 8 GB/s translates to roughly 256 MiB of KV data per 30 ms. If your per‑request token count pushes the KV size beyond 1 GiB, you’ll start to see tail spikes unless you overlap I/O with compute or upgrade to PCIe 5.0.
Q3. Does pinned memory increase the risk of out‑of‑memory (OOM) errors?
Pinned memory is reserved at the kernel level, bypassing the normal page‑faulting mechanism. If the total pinned allocation exceeds the physical RAM, the kernel will reject the request, leading to an OOM at the process start. Always verify ulimit -l and the system’s mlock policy before scaling pinned buffers.
Q4. What NCCL version should I run for best stability?
NCCL 2.20+ introduces topology‑aware tree algorithms that automatically handle asymmetric NVLink groups. Pair it with CUDA 12.2 or later to benefit from improved stream‑priority handling.
Q5. Can I mix vLLM and SGLang in the same cluster?
Yes, but you must isolate their KV spill directories and ensure that their NCCL environment variables do not conflict. Running them on separate NUMA nodes eliminates cross‑contamination of pinned buffers.
json
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "When should I prefer vLLM over SGLang?",
"acceptedAnswer": {
"@type": "Answer",
"text": "If your workload consists of many short, high‑throughput requests and you have ample host RAM for pinned
Top comments (0)