Learn
Lesson · Queues and Utilisation · Variability and pooling

Many Servers: Pooling, and Erlang C

Split traffic evenly across four servers, each with its own queue, and the utilisation is identical to pooling them behind one queue — but the waiting is not. At λ = 3, μ = 1 and s = 4 the pooled queue waits 27/53 of a second where a separate queue waits 3. Erlang C is the instrument that prices the difference.

a = λ/μ offered load in servers ρ = a/s C(s, a) the chance an arrival has to wait at all L_q = C·ρ/(1 − ρ) W_q = L_q/λ λ = 3, μ = 1, s = 4: pooled W_q = 27/53 ≈ 0.51 s four separate queues at the same ρ = 3/4: W_q = 3 s, a ratio of 53/9
One queue of s servers, against s queues of one

Core ideas

What this lesson establishes

The design idea is the whole lesson and the formula is only the instrument that puts a number on it.

1

A separate queue can be idle while another waits

That sentence is the entire mechanism. Four queues of one server each will, sooner or later, have a server with nothing to do while somebody waits in another line, and every such moment is capacity that was paid for and not used. One queue in front of four servers makes that state impossible.

2

The utilisation is identical either way

Splitting λ four ways across four servers gives each ρ = λ/(4μ), exactly the pooled ρ = a/s. So this is not a comparison between a busy system and a quiet one: the same work, the same servers, the same fraction of time busy, and a different amount of waiting.

3

Erlang C is stated here, not derived

The formula below comes out of a birth–death chain whose service rate is min(n, s)μ, and that derivation is Operations Research, markov-chains-decisions-and-queues/multiple-servers-and-erlang-c. What is owned here is the design conclusion, and the formula is used as an instrument for reaching it.

The material

Pooling, and the formula that prices it

The offered load in servers, the Erlang C formula as stated, the worked comparison, and what pooling costs in practice.

Definition · Offered load, and the M/M/s queue

M/M/s is the M/M/1 model with s identical servers behind one queue. The offered load a = λ/μ is measured in servers: it is how many servers the work would keep permanently busy. The per-server utilisation is ρ = a/s, and the system settles when ρ < 1. The server count on this path is always s.

Definition · Erlang C, stated

The probability that an arrival has to wait at all is C(s,a) = [a^s/(s!(1 − ρ))] ÷ [Σ_(n<s) aⁿ/n! + a^s/(s!(1 − ρ))].

From it, L_q = C(s,a)·ρ/(1 − ρ) and W_q = L_q/λ by Little's Law. The derivation is not given here: it is Operations Research, markov-chains-decisions-and-queues/multiple-servers-and-erlang-c, and this course's list of what it does not cover says the same.

At s = 1 the formula collapses to C = ρ and the single-server results of “The M/M/1 Queue”, which is the check worth doing first on any implementation of it.

λ = 3 / s μ = 1 / s per server s = 4 a = λ/μ = 3 servers' worth of work ρ = a/s = 3/4 pooled M/M/4 C(4, 3) = 27/53 ≈ 0.5094 the chance of waiting at all L_q = (27/53)(3) = 81/53 ≈ 1.528 W_q = L_q/λ = 27/53 ≈ 0.5094 s four separate M/M/1 queues, λ/4 = 3/4 each, same ρ = 3/4 L_q = ρ²/(1 − ρ) = 9/4 per queue W_q = L_q/(3/4) = 3 s 3 ÷ 27/53 = 53/9 ≈ 5.9 the cost of splitting the traffic

Nearly six times the wait, for the same machines under the same load. The split system is not overloaded and is not misconfigured; it is simply wasting the moments when one of its servers is free and one of its queues is not.

How the advantage moves with load

Pooling saves more seconds as the system gets busier and a larger multiple of the wait when it is quiet, and both halves of that are worth carrying. At ρ = 1/2 the pooled queue waits 2/23 of a second against 1 second separate — a ratio of 23/2 but a saving of under a second. At ρ = 3/4 the ratio is 53/9 and the saving is about two and a half seconds. At ρ = 9/10 the pooled wait is 4374/2221 against 9, a ratio of about 4.6 and a saving of about seven seconds.

So the headline “pooling matters most under load” is true of the seconds and false of the ratio, and it is the seconds that show up in an incident. The lab prints both rows at whatever λ, μ and s you set, so the two readings can be compared directly rather than argued about.

Pooling is not free, and the costs are real ones rather than rounding. A shared queue needs a dispatcher, which is a component that can itself queue or fail. Work that is not interchangeable — a session pinned to a server, a cache warmed for one shard — loses locality when it is pooled, and that shows up as a larger S, which the previous lesson says is multiplied by everything. The question is whether the factor gained on waiting exceeds the factor lost on service.

The same argument explains why a few large machines usually beat many small ones at the same total capacity, why a shared thread pool beats a pool per endpoint, and why sharding a workload that does not need to be sharded is a latency decision as well as a data one — which is where Partitioning and Load Balancing picks it up.

Interactive

Many servers, and pooling

One queue of s servers against s queues of one

Pooling, and Erlang Cone queue of s servers against s queues of one, at the same total load
pooled M/M/ss separate M/M/1the ratio

Method

Comparing a pool against a split

The comparison is only honest if both arms carry the same total load on the same servers.

1

Compute the offered load in servers

a = λ/μ. This is the number of servers the work would keep permanently busy, and it is the input Erlang C actually takes.

2

Get the per-server utilisation and check it

ρ = a/s < 1, or nothing settles in either arm. Both arms have the same ρ by construction, which is what makes the comparison mean anything.

3

Compute the pooled wait

C(s,a), then L_q = C·ρ/(1 − ρ), then W_q = L_q/λ. The lab prints all three exactly, and s = 1 should reproduce M/M/1.

4

Compute one separate queue at λ/s

It is an M/M/1 queue at the same ρ, so L_q = ρ²/(1 − ρ) and W_q = L_q/(λ/s), the closed forms of “The M/M/1 Queue”.

5

Report both the ratio and the seconds

The ratio is largest at light load and the absolute saving is largest at heavy load, and a decision usually turns on the second. Say which you are quoting.

Pooling, priced

Score 0 / 0

Four servers, one queue or four

Three requests a second into servers that manage one a second each. The two arrangements are indistinguishable on a utilisation dashboard.

λ = 3 / s μ = 1 / s each s = 4 a = λ/μ = 3 ρ = a/s = 3/4 both arrangements pooled, one queue of four servers C(4, 3) = 27/53 the chance of waiting at all ≈ 51% L_q = (27/53)(3/4)/(1/4) = 81/53 ≈ 1.53 waiting W_q = (81/53)/3 = 27/53 s ≈ 0.51 s split, four queues of one server, 3/4 per second each L_q = (3/4)²/(1/4) = 9/4 per queue W_q = (9/4)/(3/4) = 3 s ratio 3 ÷ (27/53) = 53/9 ≈ 5.9 saving 3 − 27/53 = 132/53 ≈ 2.49 s per request

Half of the pooled arrivals do not wait at all — C(4,3) ≈ 0.51 is the chance of waiting, and the other half find a free server. In the split arrangement an arrival joins whichever line it was routed to and waits behind whatever is in it, with three idle-capable servers elsewhere.

For a faded rehearsal, keep μ = 1 and s = 4 and drop the load to λ = 2. The supplied first move is a = 2 and ρ = 1/2. Compute the pooled W_q, compare it with the separate 1 second, and notice that the ratio went up while the seconds saved went down.

Common mistakes

1
Assuming an even split is as good as a poolIt is as good on a utilisation dashboard and nearly six times worse on waiting at ρ = 3/4. Evenness is not the issue: the loss comes from moments when one server is idle and another queue is not, and a perfectly even split still has them, because arrivals are random.
2
Comparing arrangements at different utilisationsQuoting a pooled queue at one load against separate queues at another measures nothing. Set a = λ/μ, set ρ = a/s, and make sure the split arm carries λ/s into each server so that both arms sit at the same ρ.
3
Pooling work that is not interchangeableThe whole argument assumes any server can take any request. Pinned sessions, warmed caches and per-shard data break that assumption, and pooling them raises S — which multiplies the entire waiting formula. The gain on the queueing factor has to beat the loss on the service factor.

Check your understanding

✓
Finish when “one queue, four servers” and “four queues, one server each” are obviously different systems to you.

You should be able to compute a, ρ and the pooled W_q from Erlang C, compute a separate queue's W_q from the M/M/1 forms, report both the ratio and the seconds, and say what would have to be true of the work for pooling to be a bad trade.

Note: Pooling and variability both reduce the waiting. The third control removes it instead: “Bounded Queues and Loss” puts a limit on how many may wait, which turns latency into rejection — and changes which arrival rate Little’s Law is entitled to use.

Kept in this browser only, for you. Nothing is sent anywhere and nothing checks it. Carry it to another device.

Feedback and recommendations

Something to change about this lesson? Write it down, tick it off when it is handled, and export the list when you want to act on it. Kept in this browser only: nothing is sent anywhere, and nobody is notified.

No recommendations yet for this lesson.