Each number is the mean of 3 runs on one server, and the 3 were within 1% of each other. Prompts of 88 tokens, new random prompts in every run, end of sequence ignored, and the same 32,096-token cache and flags as before, with vLLM's cache set to the same size. "One, then the other 31": the 31 were sent 0.3 seconds after the first. "14, then the other 18": half a second apart.
With the arrival fixed, the path no longer changed from run to run. We ran the two cases at 1,000 tokens ten more times each on one server. All 32 at the same step was fast in 10 of 10 runs, at 1,331 to 1,345 output tokens a second, and one request first was slow in 10 of 10, at 799 to 803. vLLM gave 1,341 to 1,348 for all three arrivals at 1,000 tokens, and matched SGLang's fast runs within 1.2% at every reply length.
All 32 at the same step were fast at every reply length in the table. The first request that does not fit still sets the full mark, but on an idle server the mark lands on an empty batch, which SGLang replaces with the new batch at the next step. So the check runs again, and the rest start one step later. This is the rule the trial run showed us.
That second step has to take all the rest. With longer replies, the arithmetic put the end of the fast path between 1,180 and 1,200 tokens, and we wrote that down before running it. At 1,180 tokens, 25 requests started on the first step and the other 7 on the next, and the runs gave 1,181 to 1,183 output tokens a second. At 1,200 tokens, 24 started and then 7 more, 1 waited for the whole first group, and the runs gave 794 to 798, against 1,175 to 1,177 for vLLM. At 1,280 tokens, 3 waited, and SGLang gave 779 to 781 against 1,125 to 1,128 for vLLM. With the queue checked at every step, SGLang started all 32 at 1,280 tokens and came within 1% of vLLM, at 1,118 to 1,122.
A smaller cache moves the same line to shorter replies. With the cache set to 24,000 tokens, 22 requests fit at full length. We worked out that all 32 at the same step would start 22, then 6 more, and leave 4 waiting at 1,000 tokens. They did, and the runs gave 792 to 793 output tokens a second. With the queue checked at every step, all 32 started and the runs gave 1,055. vLLM on the same cache gave 1,105 to 1,106.
One request first, then the other 31, was slow at every length from 960 tokens. In each case, the requests that waited were exactly the ones the cache had no room for at full length: 2, 3, 4 and 6. At 900 tokens all 32 fit, and every arrival was fast.
In a slow run, one waiting request costs about as much as six. With 928-token replies and one request first, 31 started and 1 waited, and the run gave 824 output tokens a second, close to the 794 with 6 waiting at 1,120 tokens. When every reply is the same length, a run lasts until its last request ends.
The fast runs lose some speed as replies get longer, from 1,457 to 1,222 tokens a second for SGLang. It starts all 32, pauses the 2 to 6 that the cache cannot finish near the end, and finishes them after. vLLM paused the same number of requests at each length, and slowed down by about the same amount.
With 1,000-token replies, a first group of 8 or fewer gave a slow run, and a group of 9 or more a fast one. That is where the arithmetic puts the line. Half a second in, a running request counts as about 770 tokens, so 9 of them leave room for the other 23 at 1,089 tokens each, and 8 do not leave room for 24. It also matches the 27 runs above: 1 or 5 requests were running when the rest arrived in the slow runs, and 12 or more in the fast ones.
The same arithmetic says the line moves with time, because a running request counts for less the longer it runs. With the rest arriving 4 seconds after the first group instead of half a second, a first group of 8 left room for the other 24, and all 32 ran together. A first group of 6 still left one waiting. On 0.5.22, which counts a running request at its whole remaining reply, 8 and then 24 still started only 29. All three came out as worked out.
The FP8 checkpoint of the same model, on a cache of the same size, took the same paths with the same counts in all 12 runs. It is faster, at 1,820 to 1,831 output tokens a second with all 32 at the same step, and the slow path cost it the same share: one request first, then the other 31, gave 1,116 to 1,120, 39% less.