Multi-Server and Finite Queues

The M/M/1 queue is the atom of queueing theory, but real systems rarely have exactly one server and infinite room. A bank has several tellers; a call centre has hundreds of agents; a telephone exchange has a fixed number of lines and simply rejects calls when they are all busy. Two generalisations cover most of real life: adding more servers, and imposing a capacity limit. Both change the arithmetic — and both contain a lesson worth real money.

M/M/c: many servers, one line

The M/M/c queue keeps Poisson arrivals at rate \lambda and exponential service at rate \mu per server, but now there are c identical servers feeding from a single shared line. The natural measure is the offered load a = \lambda/\mu (how many servers' worth of work arrives), and the utilisation per server is \rho = a/c = \lambda/(c\mu). Stability now needs \rho < 1, i.e. c > a.

The probability that an arriving customer finds every server busy and must wait is the famous Erlang-C formula C(c, a). Once you have it, the mean wait in the queue is beautifully compact:

W_q = \frac{C(c, a)}{c\mu - \lambda} = \frac{C(c, a)}{\mu\,(c - a)}, \qquad L_q = C(c,a)\,\frac{\rho}{1-\rho}.

You do not need to memorise Erlang-C to feel its effect. Fix the workload and slide the number of servers: the wait does not merely shrink, it collapses.

With an offered load of a = 2, three servers (\rho = 0.67) already keep the average wait modest; a fourth roughly halves it again; a fifth all but eliminates it. Each server bought near the "knee" of the curve buys an enormous reduction in waiting — the same congestion-explosion story as M/M/1, run in reverse.

The pooling benefit

Here is the insight that redesigned banks, post offices and airport security. Suppose you have c servers and a crowd to serve. You can run one shared line feeding all c servers (an M/M/c system), or split the crowd into c separate lines, each an independent M/M/1. Same servers, same total arrival rate — yet the single shared line delivers a dramatically shorter average wait.

This is why the snake-line at the bank, the single queue at passport control, and the shared pool of call-centre agents all beat the old "pick a lane and pray" arrangement. Combining queues is one of the cheapest performance improvements in operations: it costs nothing but a bit of rope and signage.

Finite queues: when the waiting room fills

Sometimes there is simply no room for an unlimited line. The M/M/1/K queue allows at most K customers in the system; an arrival that finds it full is turned away — blocked and lost. Because the number in the system can never exceed K, such a queue is always stable, even when \rho \ge 1 — overload no longer means an infinite line, it means a higher loss rate.

The purest case is M/M/c/c: c servers and no waiting room at all (capacity = c). This is the model of a telephone trunk group — c lines, and a call arriving when all are busy simply gets a busy tone. The chance of that is the Erlang-B loss formula:

B(c, a) = \frac{a^{c}/c!}{\displaystyle\sum_{k=0}^{c} a^{k}/k!}.

Erlang-B is one of the oldest results in the field — Agner Erlang derived it for the Copenhagen Telephone Company in 1917 — and it still sizes call centres, cellular base stations and server pools today: choose c large enough that B(c, a) (the fraction of blocked calls) drops below your target.

Worked example

A print room receives \lambda = 18 jobs per hour; one printer clears \mu = 20 per hour. As M/M/1 the utilisation is \rho = 0.9 — the danger zone — and the average number waiting is L_q = \rho^2/(1-\rho) = 0.81/0.1 = 8.1 jobs. Now add an identical second printer, making it M/M/2 with the same total work (offered load a = 18/20 = 0.9, per-server utilisation \rho = 0.45). The Erlang-C machinery gives a probability of waiting of only about 0.23, and L_q \approx 0.23 \times 0.45/0.55 \approx 0.19 jobs — a queue that has all but vanished. One extra printer took the backlog from eight jobs to a fifth of a job, because it pulled the system back from the cliff edge.

Almost, but not quite — and the difference is instructive. A single fast server at rate 2\mu clears each job in half the time, so once you reach the server you are served faster. Two servers at rate \mu can serve two customers at once, which shortens the queue, but each individual job still takes its full time. For light loads the single fast server wins on total time in system; for the waiting-line length the two-server setup is very competitive. Real designers weigh both, plus the awkward truth that one fast server is a single point of failure while two servers degrade gracefully.

The most common self-inflicted wound in service design is splitting one pooled queue into several private ones — a lane per till, a dedicated agent per client, a separate stack per clerk. It feels fairer and more organised, but it strictly increases the average wait: sooner or later someone is stuck behind a slow job while another server sits idle a metre away. Whenever you can, feed many servers from one line. The supermarket that switched to a single snake-queue did not add a single checkout — it just stopped wasting the ones it had.