Loading video...

Video Failed to Load

Go Home

Batching strategies in LLM inference, clearly explained! (bookmark it) - Static - Dynamic - And continuous batching I wrote a detailed article explaining how each works and why serving LLMs is a different problem from traditional ML inference. The article is quoted below.

30,234 views • 1 month ago •via X (Twitter)

10 Comments

Hussain Hashim | Building SundayBack's profile picture
Hussain Hashim | Building SundayBack1 month ago

@akshay_pachaar always wondered how batching affects LLMs specifically. gonna dive into your article, thanks for breaking it down!

Vikrant Guleria's profile picture
Vikrant Guleria1 month ago

Continuous batching solved the head-of-line blocking problem but introduced its own headache with KV cache fragmentation once you have dozens of sequences finishing at different times. PagedAttention style memory management ends up being just as important as the batching strategy itself.

Gregor's profile picture
Gregor1 month ago

hit this last month self-hosting a small model. one long completion was holding the whole batch hostage and my p99 looked terrible while p50 was fine. took embarrassingly long to trace it. does the article explain why most frameworks still default to static?

Workspai's profile picture
Workspai1 month ago

LLM inference really is its own kind of systems problem.

Anoy's profile picture
Anoy1 month ago

continuous batching is the one that changed everything for me.

DISCOVER Robotics's profile picture
DISCOVER Robotics1 month ago

LLM inference isn't just about generating tokens—it's about deciding which tokens to generate next across hundreds of concurrent requests.

Grace Green's profile picture
Grace Green1 month ago

Great breakdown! Dynamic batching seems like a real game-changer for LLM inference. Looking forward to diving into the article to learn more!

AI Mastery Guide's profile picture
AI Mastery Guide1 month ago

Great breakdown, saving this one

Lee Garcia's profile picture
Lee Garcia1 month ago

Nice

Taiko TOEDA's profile picture
Taiko TOEDA1 month ago

One dimension these comparisons almost never carry: batching changes the text, not only the schedule. Someone published a clean measurement of it today, on llama.cpp with greedy decoding at temperature 0. Sequential runs were byte identical. At 64 slots, eight distinct prompts produced 27 distinct answers, and the same prompt returned up to five completions depending on which slot it landed in. The part he did not expect: for two of the three prompts he checked, none of the eight batched slots matched the sequential greedy output. Batching was not selecting among answers the model gives, it was producing ones it does not give at parallel 1. My own numbers agree from a different angle, repeats inside one configuration byte identical at 200 of 200 and agreement dropping to 112 of 200 when only the speculative path changed. The practical consequence for someone using your article to pick a strategy is that you evaluate at parallel 1 and serve at 64, so the thing you validated is not the thing you ship. Worth a line beside the throughput charts.

Related Videos

Continuous batching in LLMs, clearly explained: (a popular LLM interview question; bookmark this) In traditional ML inference, a batch is a matrix. Every input is padded to the same length, one forward pass runs, and every row finishes at the same moment. LLM decoding does not work that way. One forward pass produces one token per sequence, so a request needs as many passes as it has output tokens, and nobody knows that count until the model emits a stop token. Under static batching, membership is fixed when the batch starts. A request that finishes in 30 tokens holds its slot until the slowest request in the same batch finishes at 400. The GPU keeps paying the full weight read for a batch that is mostly empty. Loading model weights out of HBM costs the same whether four slots are producing tokens or one. Continuous batching moves the decision boundary. Instead of scheduling once per batch, the scheduler runs a single forward pass, gets control back, and decides again. A finished request leaves at the next iteration boundary, and a queued request takes its slot right there. No slot stays reserved for work that is already done. Anyscale benchmarked both OPT-13B on a single A100. With uniform generation lengths, the two policies came out about level (as expected), and as output length variance rose, static batching fell to around 81 tokens per second while vLLM reached 23x the throughput of naive Hugging Face serving. Variance drives the entire gap. Production traffic mixes 30-token replies with 400-token ones, which is exactly the condition static batching handles worst. None of this alters the model. vLLM, SGLang, TGI, and TensorRT-LLM all run it by default, and NVIDIA ships the same mechanism under the name in-flight batching. The animation below runs both policies on the same 16 requests and the same 4 slots, stepping in lockstep. The only difference is when a new request is allowed in. To dive deeper into continuous batching specifically, I wrote a full breakdown of the scheduler underneath it. It covers what happens between two forward passes, how tokens get handed out against a fixed budget, why the scheduler needs no separate path for prefill and decode, and what preemption costs you when the KV cache fills up mid-generation. Read it below.

Avi Chawla

16,140 views • 2 months ago