LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 177 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/8
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/11
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageClustering and PCACore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/24
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernanceData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Reproducible ML Study
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/16
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabJAX for PyTorch ResearchersContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/19
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning & Test-Time Compute
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
🔬Project Deep Dives0/17
Deep Dive - vLLMDeep Dive - SkyRLDeep Dive - FlashAttentionDeep Dive - FlashInferDeep Dive - DeepGEMMDeep Dive - NCCLDeep Dive - MegatronDeep Dive - DeepSpeedDeep Dive - RayDeep Dive - MLflowDeep Dive - PyTorchDeep Dive - TransformersDeep Dive - SGLangDeep Dive - slimeDeep Dive - DeepEPDeep Dive - TinkerDeep Dive - Light-PEFT
Back to Topics
LearnProject Deep DivesDeep Dive - SGLang
🚀HardInference Optimization

Deep Dive - SGLang

Read SGLang from frontend program to GPU step: RadixAttention, scheduling, constrained decoding, speculative execution, parallelism, and production boundaries.

26 min read
Learning path
Step 173 of 177 in the full curriculum
Deep Dive - TransformersDeep Dive - slime

Personalize this lesson

Adapt explanations and teaching visuals to your background and preferred voice.

An LLM request can be a single prompt, or it can be a program: retrieve evidence, ask for several candidates, select one, call a tool, then generate a structured answer. A server that treats every step as an unrelated text completion repeats prefixes and loses the structure the application already knows.

SGLang co-designs two layers for that workload. Its frontend lets Python code describe generation, choices, roles, and control flow. Its SGLang Runtime (SRT) turns those requests into continuously batched GPU work, with a radix-tree key-value (KV) cache, grammar-aware decoding, speculative execution, and distributed model execution. The frontend is optional: an OpenAI-compatible request can enter SRT directly. The runtime is the common path either way.

This chapter follows one request from a frontend expression or HTTP payload through tokenization, prefix matching, scheduling, model execution, and streamed output. Keep three signals in view: time to first token (TTFT), inter-token latency (ITL), and tokens per second. SGLang's optimizations change those signals by changing how much state is reused and how much work the scheduler can overlap.

What SGLang is for

The original SGLang paper describes a frontend language plus a runtime for efficient execution of structured language-model programs.[1]Reference 1SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104 The current repository describes SGLang as a serving framework for language and multimodal models, with an OpenAI-compatible API, broad model support, and hardware backends.[2]Reference 2SGLang Source Repositoryhttps://github.com/sgl-project/sglang Those descriptions point to a useful distinction:

Entry pathReader writesSGLang must optimizeGood fit
Frontend program@sgl.function, sgl.gen, sgl.select, roles, control flowShared prefixes, parallel program branches, output dependenciesAgents, few-shot programs, extraction, multi-turn workflows
OpenAI-compatible APIJSON chat or completion requestBatching, KV reuse, sampling, streamingDrop-in model endpoint
Offline enginePython calls against sgl.EngineBatch admission and reusable cache stateEvaluation, replay, test fixtures
RL rollout clientRequests from a trainer or environmentThroughput, weight refresh, deterministic boundariesPost-training and verifiable rewards

The program surface can make repeated context visible. A system prompt, demonstrations, and retrieved documents become a shared prefix instead of three independently serialized strings. The runtime still needs an exact token match, so application-level similarity is not enough. A changed space, chat-template token, adapter identifier, or cache salt can split the prefix.

SGLang also serves requests that never use the frontend. This matters when comparing engines. A benchmark that sends plain OpenAI requests measures SRT's serving path, not the convenience or scheduling hints supplied by the frontend. A program benchmark adds branch parallelism, variable binding, and prefix reuse to the workload.

Frontend: a small intermediate representation for model calls

The public sgl module exposes a few operations with clear semantics. sgl.gen asks for model tokens, sgl.select chooses among explicit strings, and role helpers add chat-template boundaries. A decorated function becomes an SglFunction; the interpreter walks its expressions and sends generated spans to a backend. The source code for these pieces lives under python/sglang/lang/ in the local clone.

structured-program.py
1import sglang as sgl 2 3@sgl.function 4def classify_and_explain(s, question): 5 s += sgl.system("Return concise, evidence-backed answers.") 6 with s.user(): 7 s += question 8 s += "\nLabel: " 9 s += sgl.select("label", ["bug", "feature", "question"]) 10 s += "\nExplanation: " 11 s += sgl.gen("explanation", max_tokens=64, stop="\n")

One generation site has a finite choice set. Another is open-ended but has a stop condition. Its result contains named values such as label and explanation, so application code can use one generation to shape the next prompt. A frontend program can also run several branches in parallel or bind a cached prefix for a batch.

The frontend doesn't make the model deterministic. Sampling parameters still apply, and a select choice can be scored with the configured method. It also doesn't guarantee that a JSON-looking prompt returns valid JSON. Use json_schema or a regex constraint when output syntax is part of the contract.

SGLang's interpreter keeps a stream executor and a program state. The stream executor submits text and generation operations to the backend; the state holds named variables and assembled text. This split lets one program use a local engine, a remote runtime endpoint, or a test backend without changing its control flow. It also means that a bug can live above SRT: an unexpected branch, a missing variable, or a chat-template mismatch may never reach the scheduler.

Runtime path: from API to model runner

For an online request, the path is roughly:

Diagram Diagram

The process split can vary with server mode and parallelism, but responsibilities stay recognizable. Entrypoints parse requests and return protocol responses. The tokenizer manager owns tokenization and detokenization boundaries. The scheduler chooses which request tokens run next. A radix cache supplies reusable KV locations. A model runner loads weights, builds a forward batch, selects attention backends, and returns logits or sampled tokens. Grammar and sampling code constrain or select the next token before the stream is updated.[3]Reference 3SGLang Documentationhttps://docs.sglang.io/

SGLang request path. Frontend and OpenAI API requests converge on tokenization, radix prefix lookup, scheduler admission, model execution, grammar-aware sampling, and streaming. Latency badges map TTFT to queue and prefill, ITL to forward and sample, and throughput to batching and kernels. SGLang request path. Frontend and OpenAI API requests converge on tokenization, radix prefix lookup, scheduler admission, model execution, grammar-aware sampling, and streaming. Latency badges map TTFT to queue and prefill, ITL to forward and sample, and throughput to batching and kernels.
Trace one request down the stack. Frontend control flow is optional, but every path converges on tokenization, radix lookup, scheduler admission, model execution, and sampling before output streams back.

Debugging starts at the handoff between stages. High TTFT with low GPU utilization points to tokenization, queue wait, prefix lookup, or admission before kernel work. Rising ITL after a model update points to forward-batch shapes, attention backend selection, collective wait, and grammar or speculative work. Malformed output calls for separating model logits from grammar masking and detokenization.

One step, one token budget

SRT maintains active requests and schedules a batch repeatedly. Decodes usually need one new token per request. Prefills need many prompt tokens. Chunked prefill divides a long prompt so it doesn't monopolize a step while decodes wait. The exact flags and defaults change by release, so inspect Scheduler.init_chunked_prefill and the server arguments for the clone's version.

Consider a teaching trace with budget six:

StepReady workTokens admittedState after step
0R0 decode needs 1; R1 prefill needs 9R0=1, R1=5R0 advances; R1 has 4 prompt tokens left
1R0 decode needs 1; R1 prefill needs 4R0=1, R1=4R1 finishes prefill
2R0 and R1 decodeR0=1, R1=1Both requests continue generation

The numbers are an invariant exercise, not a performance claim. The scheduler spends a bounded token budget while keeping decode work eligible. A larger prefill slice may improve TTFT for new prompts but can delay existing decodes. A smaller slice can protect ITL but stretch prompt processing.

SGLang also has an overlap path. CPU scheduling, token movement, and GPU execution can be pipelined when the backend and flags permit it. Overlap hides some host work, but it adds queues and synchronization. A race in request state, a delayed grammar update, or a stale KV location can become a correctness bug rather than a simple latency regression.

RadixAttention: prefix reuse as a tree

RadixAttention is SGLang's name for using a radix tree to find reusable KV-cache prefixes. It isn't an attention kernel. The tree stores token-key paths and references to KV locations; an attention backend later reads those locations. The distinction matters when reading performance reports or debugging a hardware-specific kernel.

Suppose two requests share tokens A B C D and then diverge:

RequestToken sequenceReused pathNew path
R0A B C D E FA B C DE F
R1A B C D X YA B C DX Y

The tree contains one shared path for the first four tokens, then two branches. A request's prefix match returns the longest cached path and the corresponding token-to-KV indices. The scheduler can skip prefill for that matched region and allocate new KV slots only for the suffix.

The local RadixKey stores token IDs plus an optional extra key. Current source uses extra keys for namespaces such as LoRA adapters, cache salt, version, or retrieval context, and the cache's match operation checks compatible keys before comparing tokens. This keeps cache namespaces disjoint as cache partitioning, not an authorization boundary.

The match is exact and page-aware. If a cache policy or backend requires aligned units, a partial final unit isn't reusable as a complete prefix. The practical result is simple: stable system prompts and demonstrations help; per-request timestamps and random IDs near the front of a prompt destroy hits.

A compact SGLang RadixAttention trace. A root lookup reaches one shared A B C D path with KV slot 12 and two live references, then branches to E F for R0 and X Y for R1. A six-token scheduler bar admits one R0 decode token and five R1 prefill tokens, leaving four R1 prompt tokens. A compact SGLang RadixAttention trace. A root lookup reaches one shared A B C D path with KV slot 12 and two live references, then branches to E F for R0 and X Y for R1. A six-token scheduler bar admits one R0 decode token and five R1 prefill tokens, leaving four R1 prompt tokens.
Follow the branch from shared prefix to divergent suffix. Radix matching chooses reusable KV state first; the scheduler then spends remaining token budget on live decodes and new prefill work.

Insert, lock, evict

A prefix cache needs ownership rules alongside its lookup map. While a request is active, its matched KV locations are protected. When a request finishes or releases a branch, nodes can become evictable. The eviction policy can be LRU or another configured strategy, but it must never reclaim state still referenced by a live request.

The source path is visible in python/sglang/srt/mem_cache/radix_cache.py:

  1. match_prefix finds the longest compatible path and returns KV indices.
  2. insert adds a new token path after forward computation.
  3. Lock and unlock operations protect prefixes while requests use them.
  4. evict removes unprotected branches according to the selected policy.

This sequence exposes a common failure. If a request's KV reference is released too early, another request can overwrite memory while the first is still decoding. If references never drop, free KV capacity shrinks until admission stalls. Instrument active references, evictable tokens, match lengths, and allocator failures together.

The cache is local to an engine or replica unless a higher-level routing layer coordinates it. A load balancer that sends identical prompts to different replicas may see low hit rates even when each replica has a healthy tree. Cache-aware routing can improve locality, but adding replicas still changes hit probability and warm-up behavior.

Structured generation: constrain the next token

Many applications need valid JSON, a tool-call schema, a regular-language field, or one label from a known set. Asking a model to "please emit JSON" is a prompt preference, not a syntax guarantee. SGLang can carry a regex, JSON schema, or choice constraint through sgl.gen and its server APIs.[4]Reference 4Structured Outputshttps://docs.sglang.io/advanced_features/structured_outputs.html

At each decoding step, a grammar engine tracks an automaton state. It computes the set of tokens that keep the partial output valid, and the sampler masks other logits. The model still chooses among allowed tokens. The grammar doesn't add facts to the model or repair a semantically wrong field.

schema-constrained.py
1import sglang as sgl 2 3@sgl.function 4def extract(s, passage): 5 s += "Extract one entity from this passage:\n" + passage 6 s += sgl.gen( 7 "record", 8 json_schema='{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}', 9 max_tokens=64, 10 )

SGLang supports multiple grammar backends in the repository. The selected backend, tokenizer, vocabulary, and schema shape affect CPU work and compatibility. A grammar with many alternatives can take more time to update than a small enum. Measure grammar preparation, per-step mask time, and end-to-end latency rather than assuming all constrained requests cost the same.

The original SGLang work also introduced compressed finite-state-machine techniques for faster structured decoding.[1]Reference 1SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104 The enduring design is the boundary: grammar state stays on the control side, while logits remain on the model side. That makes constraints inspectable and lets the runtime reuse model KV state even when grammar states differ.

Failure handling needs an explicit policy. If no token satisfies the grammar, the request should return an error or a clearly marked incomplete result. Retrying with a looser grammar can change semantics. Don't silently strip braces or run a best-effort JSON parser and call the result valid.

Speculative decoding: verify a draft in parallel

Autoregressive decoding normally produces one token per target-model forward step. Speculative decoding asks a cheaper draft path for several candidates, then lets the target model verify them in one pass. Accepted tokens advance the sequence faster; rejected tokens fall back to a target-sampled token.

SRT exposes several speculative algorithms, including EAGLE, EAGLE3, n-gram lookup, standalone draft models, and DFlash-family methods in the cloned version. The enum and worker registry live under python/sglang/srt/speculative/. The exact flags and model requirements are version-specific, so check SpeculativeAlgorithm and its validator before enabling a mode.[5]Reference 5Speculative Decodinghttps://docs.sglang.io/advanced_features/speculative_decoding.html

An abstract step looks like this:

PhaseWorkState
DraftPropose y1 ... yk from a cheap pathDraft tokens and optional draft KV
VerifyTarget scores candidates with one batched forwardTarget logits and acceptance tests
CommitKeep accepted prefix, sample after first rejectionMain KV extends by accepted tokens

EAGLE-2 and EAGLE-3 research explores draft generation from target-model representations and tree-shaped candidates.[6]Reference 6EAGLE-2: Faster Inference of Language Models with Dynamic Draft Treeshttps://arxiv.org/abs/2406.16858[7]Reference 7EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Testhttps://arxiv.org/abs/2503.01840 DFlash-family work targets faster diffusion-style or parallel draft paths in newer SGLang releases.[8]Reference 8DFlash: Block Diffusion for Flash Speculative Decodinghttps://arxiv.org/abs/2602.06036 The implementation must still preserve token ordering, position IDs, grammar state, and cache ownership.

Speculation helps when acceptance is high and draft work is cheaper than target work. It can hurt when the model is uncertain, prompts are short, grammar masks reject candidates, or draft KV consumes capacity needed by ordinary requests. Track acceptance length, draft and verify latency, rejected tokens, extra memory, and ITL by model and workload.

Parallelism and prefill-decode disaggregation

SGLang maps model work onto hardware through several parallelism axes. Names vary by model, but the trade-offs are stable:

AxisWhat is splitHelps withCosts
Tensor parallelism (TP)Matrix dimensions across devicesFit and per-request computePer-layer collectives
Pipeline parallelism (PP)Layer ranges across stagesFit depth across nodesPipeline bubbles and stage sync
Data parallelism (DP)Full model replicas or request groupsIndependent throughputWeight memory and routing
Expert parallelism (EP)Mixture-of-Experts expertsExpert capacity and load balanceToken routing and all-to-all
Context or sequence pathsSequence positions or attention workLong contexts and bandwidthExtra communication and layout constraints

The runtime has to align these choices with attention backends, quantization, CUDA graphs, and model-specific layers. A TP setting that fits weights can still reduce ITL if collectives dominate. A DP replica can raise throughput while lowering prefix-cache locality. Read the parallelism docs and benchmark on the target topology before copying a flag set.[9]Reference 9SGLang Server Arguments and Parallelismhttps://docs.sglang.io/advanced_features/server_arguments.html

Prefill and decode have different resource shapes. Prefill consumes many prompt tokens and tends to be compute-heavy. Decode consumes one or a few tokens per request and repeatedly reads KV memory, making it more latency and memory sensitive. Prefill-decode (P/D) disaggregation places them on separate worker pools and transfers KV state between them.[10]Reference 10Prefill-Decode Disaggregationhttps://docs.sglang.io/advanced_features/pd_disaggregation.html

The P/D path can protect decode latency from a long prompt and let each pool scale for its own traffic. It adds transfer bytes, synchronization, routing, and a cache locality decision. A prompt that is prefetched on one node but decoded on another needs a reliable connector and enough bandwidth. If transfer time exceeds the compute saved, colocated execution wins.

Diagram Diagram

P/D disaggregation is not a free "scale out" switch. Test queueing at both pools, transfer latency, failure recovery, and cache hit rate. A decode worker that loses its prefill connection needs a clear retry or cancellation path so stale KV state isn't treated as valid.

Applications and workload shape

SGLang's main advantage appears when request structure matches runtime structure. Choose the smallest example that exposes that match:

ApplicationRuntime opportunityWhat can break
Agent loopReuse system and tool instructions; batch independent branchesBranches diverge early, tool latency dominates
Retrieval-augmented generationCache stable prompt and template prefixRetrieved chunks change order or include random IDs
Structured extractionGrammar masks invalid tokensSchema is large or semantically underspecified
Reasoning and self-consistencyRun candidate branches togetherMore samples multiply KV and verification cost
Multi-turn chatKeep conversation prefix hotContext trimming or replica routing loses locality
Multimodal chatShare batching and model runner infrastructureMedia preprocessing, transfer, and model support vary
RL rolloutHigh-throughput generation and weight updatesVersion skew between trainer and rollout workers

The paper's evaluations span agent control, logical reasoning, few-shot tasks, JSON decoding, retrieval-augmented generation, and multi-turn chat.[1]Reference 1SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104 Treat those workloads as evidence for mechanisms, not a current throughput guarantee. A release, GPU, model, tokenizer, and request mix can change the winner.

Strengths, weaknesses, and failure boundaries

DimensionStrengthBoundary or weakness
Programming modelFrontend names generation sites and branchesExtra abstraction can hide a prompt or state bug
Prefix reuseRadix tree finds exact shared token pathsSmall prompt changes or replica routing erase hits
SchedulingContinuous batching, chunked prefill, and overlap share a stepQueue policy can trade TTFT, ITL, and fairness
Structured outputGrammar constraints enforce syntax during samplingGrammar preparation and per-step masks add CPU work
SpeculationAccepted draft tokens reduce target-model stepsLow acceptance turns draft work into overhead
HardwareMultiple attention backends and parallelism axesCompatibility matrix changes quickly by model and accelerator
ScaleP/D and distributed execution separate bottlenecksKV transfer, collectives, and routing add failure surfaces
EcosystemOpenAI API, frontend, model integrations, and RL clientsAPI compatibility doesn't mean identical sampling or error behavior

Most incidents fit one of four boundaries:

  1. Prompt boundary: tokenization or chat-template output differs from what the application expects.
  2. Cache boundary: prefix keys, references, or allocator capacity don't match request lifetime.
  3. Execution boundary: a scheduler batch, attention backend, or collective stalls or returns wrong shapes.
  4. Output boundary: grammar, sampler, detokenizer, or stream assembly changes the result.

Separate those boundaries in telemetry. A single end-to-end latency number can't tell whether a prefix hit helped or whether a grammar mask consumed the saved time.

A production failure drill

Suppose a service reports low GPU utilization, high TTFT, and almost no radix hits.

  1. Log tokenized prompt lengths and chat-template versions. A frontend and OpenAI caller may be producing different prefix bytes.
  2. Check router placement. Identical requests on different replicas won't share a local tree unless routing is cache-aware.
  3. Inspect scheduler queue wait, tokenizer time, and max_prefill_tokens or chunked-prefill settings.
  4. Check KV allocator free capacity and evictable tokens. A full cache can trigger admission stalls even when compute is idle.
  5. Compare grammar and speculation flags. CPU grammar work or rejected drafts can make GPU gaps look like a cache issue.
  6. Run a fixed prompt replay with speculation and grammar disabled. This gives a clean baseline for model-runner and backend timing.

Now invert the symptoms: high GPU utilization, good radix hits, but ITL spikes when a long prompt arrives. That points toward prefill scheduling, chunk size, collective wait, or P/D routing. Increasing cache size won't fix a token-budget policy that lets prefill consume every step.

Project identity

The SGLang paper came from researchers and engineers around UC Berkeley and the LMSYS community, including Lianmin Zheng, Liangsheng Yin, Zhiqiang Xie, Ying Sheng, Ion Stoica, Joseph Gonzalez, and collaborators.[1]Reference 1SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104 LMSYS is a nonprofit organization that incubates open-source systems and research projects; SGLang is one of its flagship projects.[11]Reference 11About LMSYS Orghttps://www.lmsys.org/about/ The current repository is a multi-contributor project rather than a single-vendor SDK, so support and performance depend on model, hardware, and release paths.

FieldCurrent project fact
OriginUC Berkeley and LMSYS researchers built SGLang around language-model programming and efficient serving. The founding paper names Lianmin Zheng, Liangsheng Yin, Zhiqiang Xie, Ying Sheng, and collaborators.[1]Reference 1SGLang: Efficient Execution of Structured Language Model Programshttps://arxiv.org/abs/2312.07104
StewardshipLMSYS, a nonprofit research organization, incubates SGLang under the sgl-project GitHub organization.[11]Reference 11About LMSYS Orghttps://www.lmsys.org/about/
Contributor pathMAINTAINER.md and CODEOWNERS define merge on-call, code-owner, write, CI, and review responsibilities.[12]Reference 12SGLang Maintainer Roleshttps://github.com/sgl-project/sglang/blob/f8e62a9224815cc9c6fc56b940eb7fde791a8870/.github/MAINTAINER.md
Source licenseCore SGLang source is Apache-2.0.[13]Reference 13SGLang Apache License 2.0https://github.com/sgl-project/sglang/blob/f8e62a9224815cc9c6fc56b940eb7fde791a8870/LICENSE
Commercial boundarySponsors, vendors, and consultants can support or integrate SGLang without owning its nonprofit-hosted repository.
Asset boundaryModel checkpoints, tokenizers, datasets, and third-party kernels can carry licenses separate from SGLang's source license.

Read the history as a sequence of co-design decisions:

Research or release threadRuntime idea it motivates
SGLang frontend plus runtime paperTreat a multi-call LM program as one schedulable workload
RadixAttentionReuse exact token prefixes through a tree of KV locations
Compressed grammar decodingKeep structured output constraints on the decoding path
v0.4 scheduler and cache-aware workReduce host scheduling overhead and preserve locality as traffic grows[14]Reference 14SGLang v0.4: Zero-Overhead Batch Scheduler, Cache-Aware Load Balancer, Faster Structured Outputshttps://www.lmsys.org/blog/2024-12-04-sglang-v0-4/
EAGLE-2 and EAGLE-3Draft and verify multiple candidate tokens[6]Reference 6EAGLE-2: Faster Inference of Language Models with Dynamic Draft Treeshttps://arxiv.org/abs/2406.16858[7]Reference 7EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Testhttps://arxiv.org/abs/2503.01840
DFlash-family researchAdd newer parallel draft paths to SGLang's speculative registry[8]Reference 8DFlash: Block Diffusion for Flash Speculative Decodinghttps://arxiv.org/abs/2602.06036
P/D and distributed runtime docsSeparate prompt compute from decode memory traffic when topology supports it[10]Reference 10Prefill-Decode Disaggregationhttps://docs.sglang.io/advanced_features/pd_disaggregation.html

The code keeps these ideas modular enough to inspect. A paper explains why a mechanism helps. A release guide explains which flags and models expose it. The local source shows ownership, state transitions, and failure handling. Read all three before making a production claim.

Code-reading route in the local clone

This walkthrough uses the official SGLang repository at commit f8e62a9224815cc9c6fc56b940eb7fde791a8870.[2]Reference 2SGLang Source Repositoryhttps://github.com/sgl-project/sglang

Read one request through these files:

  1. python/sglang/lang/api.py: public function, gen, select, role, regex, and JSON-schema operations.
  2. python/sglang/lang/ir.py: expression nodes and the program representation passed to a backend.
  3. python/sglang/lang/interpreter.py: program state, stream executor, batch execution, and optional prefix tracing.
  4. python/sglang/srt/entrypoints/http_server.py: online request boundary and server routes.
  5. python/sglang/srt/managers/tokenizer_manager.py: tokenization, request state, and output handoff.
  6. python/sglang/srt/managers/scheduler.py: token pools, chunked prefill, overlap setup, admission, and scheduling loop.
  7. python/sglang/srt/mem_cache/radix_cache.py: match_prefix, insert, reference protection, and eviction.
  8. python/sglang/srt/model_executor/model_runner.py: model loading, forward-batch setup, attention backends, and parallel state.
  9. python/sglang/srt/constrained/grammar_manager.py: grammar backend selection and constrained token state.
  10. python/sglang/srt/speculative/spec_info.py: speculative algorithm registry and draft/verify capability checks.
  11. python/sglang/srt/disaggregation/prefill.py and decode.py: P/D role boundaries and KV transfer lifecycle.

Keep these invariants beside the source:

  • A frontend generation name identifies a value in program state; it isn't a cache key by itself.
  • A radix match is exact over token IDs and compatible extra keys; semantic similarity doesn't qualify.
  • A scheduler may execute only tokens backed by valid KV locations and request ownership.
  • A grammar filter can remove logits but can't make an invalid model state valid.
  • Speculative verification can commit only accepted tokens in order and must update grammar and KV state together.
  • P/D transfer must complete before decode consumes the transferred KV range.

Rerun and measure

Start with a tiny local engine or mock backend. Verify the frontend program returns named values. Then send the same tokenized prompt twice and compare matched-prefix length and prefill work. Add a third request with one changed system-prompt token to prove that reuse is exact.

For serving tests, record:

LayerMinimum signals
Inputtoken count, template version, media preprocessing time
Admissionqueue wait, matched-prefix tokens, allocated KV tokens
Schedulerbatch token count, prefill chunks, overlap delay, preemptions
Model runnerforward time, attention backend, collectives, GPU utilization
Grammar or speculationmask time, accepted draft length, rejection count
OutputTTFT, ITL, finish reason, detokenization time

Change one mechanism at a time. Compare four fixed configurations: plain decoding, radix cache on, grammar on, and speculation on. For P/D, compare colocated and disaggregated modes with the same prompt mix. Keep quality and correctness checks beside latency, because a faster malformed JSON response is a regression.

Key takeaways

  • SGLang combines a program frontend with SRT, but plain API requests can use SRT without the frontend.
  • Frontend expressions expose generation sites, branches, and constraints that a flattened prompt hides.
  • RadixAttention is a prefix-cache data structure and scheduling aid, not an attention kernel.
  • A token budget, chunked prefill, and overlap let decodes and prefills share repeated steps, with TTFT and ITL trade-offs.
  • Grammar constraints mask invalid next tokens; they don't guarantee semantic correctness.
  • Speculative decoding trades draft work and memory for accepted target tokens. Acceptance length is the key health signal.
  • TP, PP, DP, EP, and P/D disaggregation solve different fit and latency problems, each with communication costs.
  • Production debugging needs token, cache, scheduler, runner, grammar, and stream signals, not one throughput number.

Explain the runtime path without looking at the diagram. Then answer why a stable system prefix helps two requests, why a grammar can increase CPU time, and why a P/D split can lose to colocated execution on a bandwidth-limited network.

Complete the lesson

Mastery Check

Answer every question, then check your score. Score 75% or higher to mark this lesson complete.

1.What does SGLang's frontend add to an inference request?
2.What qualifies as a radix prefix-cache match?
3.Why use chunked prefill when decodes are waiting?
4.What does grammar-constrained decoding do at a token step?
5.When is speculative decoding most likely to help?
6.What is a likely cost of increasing tensor parallelism?
7.What does prefill-decode disaggregation separate?
8.A service has low radix hits, high TTFT, and low GPU utilization. What should you inspect first?

8 questions remaining.

Next Step
Continue to Deep Dive - slime

You now have the serving-runtime model needed to understand how an RL post-training system drives SGLang rollouts, synchronizes weights, and measures generated trajectories.

PreviousDeep Dive - Transformers
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

SGLang: Efficient Execution of Structured Language Model Programs

Zheng, L., Yin, L., Xie, Z., et al. · 2024 · NeurIPS 2024

SGLang Source Repository

SGLang Project · 2026

SGLang Documentation

SGLang Project · 2026

Structured Outputs

SGLang Project · 2026

Speculative Decoding

SGLang Project · 2026

EAGLE-2: Faster Inference of Language Models with Dynamic Draft Trees

Li, Y., Wei, F., Zhang, C., and Zhang, H. · 2024

EAGLE-3: Scaling up Inference Acceleration of Large Language Models via Training-Time Test

Li, Y., Wei, F., Zhang, C., & Zhang, H. · 2025

DFlash: Block Diffusion for Flash Speculative Decoding

Chen, J., Liang, Y., and Liu, Z. · 2026 · ICML 2026

SGLang Server Arguments and Parallelism

SGLang Project · 2026

Prefill-Decode Disaggregation

SGLang Project · 2026

About LMSYS Org

LMSYS Org · 2026

SGLang Maintainer Roles

SGLang Project · 2026

SGLang Apache License 2.0

SGLang Project · 2026

SGLang v0.4: Zero-Overhead Batch Scheduler, Cache-Aware Load Balancer, Faster Structured Outputs

SGLang Team · 2024

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.