The Problem with Static Batching
Traditional inference systems use static batching:- Head-of-line blocking: Fast requests wait for slow ones
- GPU underutilization: Batch shrinks as requests finish
- Increased latency: Requests queue while waiting for batch slots
Continuous Batching Solution
SGLang implements continuous batching:- No head-of-line blocking: Requests finish independently
- Higher GPU utilization: Batch stays fuller longer
- Lower latency: New requests start immediately
Continuous batching is sometimes called “iteration-level scheduling” or “dynamic batching”.
Implementation in SGLang
Scheduler Event Loop
The scheduler runs a continuous loop inpython/sglang/srt/managers/scheduler.py:
python/sglang/srt/managers/scheduler.py:1110-1135
Batch Composition
Every iteration, the scheduler rebuilds the batch:python/sglang/srt/managers/scheduler.py:747-761
Request Phases
Requests go through distinct phases:1. Prefill (Extend) Phase
Purpose: Process input tokens and generate KV cache- Processes all input tokens in parallel
- Allocates KV cache memory
- Compute-intensive (matrix multiplications)
- One-time cost per request
2. Decode Phase
Purpose: Generate output tokens one at a time- Generates one token at a time
- Incrementally extends KV cache
- Memory-bandwidth-bound
- Repeated until stopping condition
Decode is typically memory-bandwidth-bound rather than compute-bound, so batching helps amortize memory access costs.
Batch Addition Logic
The scheduler intelligently adds requests to the batch:python/sglang/srt/managers/schedule_policy.py
Resource Constraints
Requests are admitted based on multiple constraints:- Token budget: Total tokens in batch
- Memory budget: Available KV cache slots
- Request budget: Maximum concurrent requests
- Batch size: Configured limits
Request Completion
Requests complete independently:python/sglang/srt/managers/scheduler.py
Each request completes as soon as it reaches its stopping condition, freeing up resources for new requests immediately.
Scheduling Policies
SGLang supports multiple policies for choosing which requests to add:FCFS (First-Come-First-Served)
Simple: Process requests in arrival orderLPM (Longest Prefix Match)
Smart: Prioritize requests with cached prefixespython/sglang/srt/managers/schedule_policy.py:242-253
LOF (Longest Output First)
Throughput-focused: Schedule long jobs firstPriority Scheduling
QoS-aware: Honor request prioritiesAdvanced Features
Chunked Prefill
Large prefill requests can be split into chunks:- Reduces TTFT (Time to First Token) spikes
- Improves fairness between long and short requests
- Better interleaving of prefill and decode
python/sglang/srt/managers/scheduler.py:763-787
Overlapped Scheduling
Overlap CPU processing with GPU execution:python/sglang/srt/managers/scheduler.py:1137-1188
Overlapped scheduling can improve throughput by 10-20% by hiding CPU overhead behind GPU computation.
Preemption
High-priority requests can preempt low-priority ones:Performance Optimization
Memory Estimation
The scheduler estimates future memory needs:The scheduler uses conservative estimation to avoid OOM, controlled by
--schedule-conservativeness (default 1.0).Token Ratio Tuning
Balance between prefill and decode:Batch Size Limits
Control batch size:Monitoring and Metrics
Key metrics to track:Best Practices
-
Right-size batch limits: Balance latency and throughput
- Smaller batches: Lower latency, lower throughput
- Larger batches: Higher latency, higher throughput
-
Use appropriate scheduling policy:
- FCFS for fairness
- LPM for cache-heavy workloads
- Priority for multi-tenant systems
-
Enable chunked prefill for mixed workloads:
- Prevents long prefills from blocking short requests
- Set chunk size to ~2048 tokens
-
Configure memory conservatively:
- Leave 10-20% headroom for scheduling flexibility
- Avoid OOM which degrades performance severely
-
Monitor and tune:
- Watch queue depth and batch utilization
- Adjust token ratios based on workload
- Profile to identify bottlenecks
Common Issues
Request Starvation
Symptom: Some requests wait very long in queue Solution:- Use FCFS or priority scheduling
- Enable preemption for high-priority requests
- Reduce max_new_tokens limits
Low GPU Utilization
Symptom: GPU not fully utilized Solution:- Increase max_running_requests
- Increase max_total_num_tokens
- Enable overlapped scheduling
- Check for CPU bottlenecks
High Memory Pressure
Symptom: Frequent eviction, OOM errors Solution:- Increase mem_fraction_static
- Reduce max_running_requests
- Enable KV cache quantization
- Use more aggressive eviction policy
Related Topics
- System Architecture - Overall system design
- Prefix Caching - Cache management with batching
- RadixAttention - Attention with shared prefixes
