Skip to main content
Continuous batching is a core scheduling technique in SGLang that allows requests to dynamically enter and exit batches without waiting for the entire batch to complete. This dramatically improves GPU utilization and reduces latency compared to traditional static batching.

The Problem with Static Batching

Traditional inference systems use static batching:
Problems:
  • 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:
Benefits:
  • 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 in python/sglang/srt/managers/scheduler.py:
Reference: python/sglang/srt/managers/scheduler.py:1110-1135

Batch Composition

Every iteration, the scheduler rebuilds the batch:
The key data structures:
Reference: 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
Characteristics:
  • 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
Characteristics:
  • 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:
Reference: python/sglang/srt/managers/schedule_policy.py

Resource Constraints

Requests are admitted based on multiple constraints:
  1. Token budget: Total tokens in batch
  2. Memory budget: Available KV cache slots
  3. Request budget: Maximum concurrent requests
  4. Batch size: Configured limits

Request Completion

Requests complete independently:
Reference: 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 order
Best for: Fair resource allocation, predictable latency

LPM (Longest Prefix Match)

Smart: Prioritize requests with cached prefixes
Best for: Maximizing cache hits, RAG applications Reference: python/sglang/srt/managers/schedule_policy.py:242-253

LOF (Longest Output First)

Throughput-focused: Schedule long jobs first
Best for: Maximizing throughput, batch jobs

Priority Scheduling

QoS-aware: Honor request priorities
Best for: Multi-tenant systems, SLA requirements
For most workloads, LPM provides the best balance of throughput and latency when prefix caching is enabled.

Advanced Features

Chunked Prefill

Large prefill requests can be split into chunks:
Configuration:
Benefits:
  • Reduces TTFT (Time to First Token) spikes
  • Improves fairness between long and short requests
  • Better interleaving of prefill and decode
Reference: python/sglang/srt/managers/scheduler.py:763-787

Overlapped Scheduling

Overlap CPU processing with GPU execution:
Reference: 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:
Configuration:

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:
Configuration:

Batch Size Limits

Control batch size:

Monitoring and Metrics

Key metrics to track:
Monitor queue depth closely - sustained queue growth indicates capacity issues.

Best Practices

  1. Right-size batch limits: Balance latency and throughput
    • Smaller batches: Lower latency, lower throughput
    • Larger batches: Higher latency, higher throughput
  2. Use appropriate scheduling policy:
    • FCFS for fairness
    • LPM for cache-heavy workloads
    • Priority for multi-tenant systems
  3. Enable chunked prefill for mixed workloads:
    • Prevents long prefills from blocking short requests
    • Set chunk size to ~2048 tokens
  4. Configure memory conservatively:
    • Leave 10-20% headroom for scheduling flexibility
    • Avoid OOM which degrades performance severely
  5. 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