AI Infra Interviews logo
🧮 Open Weights & Serving Engines
Foundational

SGLang Server Arguments That Matter

SGLang's tuning model is different from vLLM's in one way that matters: it exposes the scheduler's aggressiveness and the static memory fraction as direct knobs, and its own documentation gives target values for the runtime signals those knobs move. That makes tuning it a measurement loop rather than guesswork. Aim for a queue of a hundred to a couple of thousand requests, token usage above 0.9, and five to eight gigabytes of free GPU memory after startup, then adjust the flags that move each one.

TL;DR: Tune against three published targets rather than against intuition. SGLang's documentation says to keep the request queue in the range of 100 to 2,000, to aim for token usage above 0.9, and to leave 5 to 8 GB of free GPU memory after startup. Each target has a flag that moves it. --mem-fraction-static sets the fraction of GPU memory given to weights plus the KV pool, and it is raised in increments of 0.01 until memory runs out, then backed off. --schedule-conservativeness controls how eagerly the scheduler admits requests, lowered toward 0.3 when the cache sits idle with work waiting and raised toward 1.3 when the pool keeps filling. --chunked-prefill-size is reduced to 4096 or 2048 when prefill runs out of memory, and --max-running-requests is reduced when decode does. RadixAttention prefix caching is on by default and is the reason to pick SGLang for workloads with shared prefixes.

The tuning loop, as the project describes it

signals to watch in the server log, with the project's own targets
  queue depth (#queue-req)       target 100 to 2,000
                                 persistently 0 means the client is not offering enough work,
                                 not that the server is fast
  token usage                    target above 0.9
                                 low usage with requests waiting means the scheduler is being
                                 too cautious
  available_gpu_mem at startup   target 5 to 8 GB
                                 more than that is unused capacity; less risks running out

the flags that move each
  available_gpu_mem  <- --mem-fraction-static, raised 0.01 at a time until it fails
  token usage        <- --schedule-conservativeness, to about 0.3 to admit more eagerly
  pool overflowing   <- --schedule-conservativeness, to about 1.3 to admit more cautiously
  prefill OOM        <- --chunked-prefill-size to 4096 or 2048
  decode OOM         <- --max-running-requests down
  stability over all <- --mem-fraction-static to 0.8 or 0.7, trading concurrency for safety
sanity: every one of these is a closed loop with an observable, which is why SGLang tuning
        converges quickly and vLLM tuning often does not, and it is worth saying so in an
        interview because it is a real difference between the two

What --mem-fraction-static actually covers

the definition, from the project's documentation
  --mem-fraction-static = (model weights + KV cache pool) / GPU memory capacity

so it is not the same thing as vLLM's --gpu-memory-utilization
  vLLM's fraction is what the engine claims before subtracting weights
  SGLang's fraction includes the weights inside the numerator

worked: a 70B model in FP8 on one 288 GB B300
  weights = 70 GB
  at --mem-fraction-static 0.85: 288 x 0.85 = 245 GB for weights plus pool
  KV pool = 245 - 70 = 175 GB
  at the corpus figure of 320 KB per token for a 70B grouped-query model:
    175e9 / 327,680 = about 534,000 tokens of cache
  at 8,192 tokens per sequence: 65 concurrent sequences at full length
  and 288 - 245 = 43 GB left, well above the 5 to 8 GB target, so this is under-allocated
    and the fraction should go up
sanity: the 5 to 8 GB target is what turns "is my configuration right" into a measurement,
        and 43 GB free means roughly 130,000 tokens of cache being left unused

RadixAttention, and when it is the reason to choose SGLang

rendering diagram…
where the gain is, as arithmetic
  an agent workload: 2,000-token system prompt and tool definitions, then a 200-token turn
  without prefix caching, prefill per request = 2,200 tokens
  with the shared prefix cached, prefill per request = 200 tokens
  prefill work saved = 2,000 / 2,200 = 91%
  at a 70B model and 2 x params x tokens FLOPs:
    saved per request = 2 x 70e9 x 2,000 = 2.8e14 FLOPs
sanity: the gain scales with the shared fraction, so it is enormous for agents and multi-turn
        chat and near zero for a workload of unique long documents, which is exactly the
        criterion for choosing this engine

The flags, grouped

GroupFlagNote
Parallelism--tp-size (--tensor-parallel-size), default 1Same divisibility constraint as any engine
Parallelism--moe-dp-size (--moe-data-parallel-size), default 1Mixture-of-experts data-parallel width
Memory--mem-fraction-staticWeights plus KV pool as a fraction of GPU memory
Memory--max-total-tokensHard bound on the token pool
Batching--chunked-prefill-size, -1 disablesLower it on prefill out-of-memory
Batching--max-running-requestsLower it on decode out-of-memory
Scheduler--schedule-conservativeness0.3 to admit eagerly, 1.3 to admit cautiously
Cache--radix-eviction-policy, default lruPrefix cache eviction
Cache--disable-radix-cacheDebugging only; turning this on in production discards the main advantage
CUDA graphs--cuda-graph-max-bs-decodeRaise to 512 or 768 at large tensor parallel degrees, at a memory cost

What interviewers are listening for

The targets, quoted as targets. An engineer who says "I tune --mem-fraction-static up in steps of 0.01 until the log shows about 5 to 8 GB of available_gpu_mem" is describing a procedure with a stopping rule, which is what the question is actually asking for. The second signal is knowing that SGLang's fraction includes the weights and vLLM's does not, because carrying a number across from one engine to the other is a common and confusing mistake. The third is naming the workload shape that makes RadixAttention worth it, since choosing an engine for a feature the traffic cannot use is the more expensive error.

Key takeaways

  • Tune against three published targets: 100 to 2,000 queued requests, token usage above 0.9, and 5 to 8 GB free after startup.
  • --mem-fraction-static is (weights plus KV pool) over GPU memory, which is a different definition from vLLM's utilization fraction.
  • --schedule-conservativeness toward 0.3 admits more eagerly; toward 1.3 admits more cautiously when the pool keeps filling.
  • Prefill out-of-memory is fixed with --chunked-prefill-size at 4096 or 2048; decode out-of-memory with --max-running-requests.
  • RadixAttention saves the shared fraction of prefill, which is over 90 percent for an agent with a 2,000-token shared prefix and near zero for unique documents.
RELATED CONCEPTS
PRACTICE THIS IN REAL QUESTIONS