M/M/c Queues and the Erlang C Formula
The formula for the probability an arriving customer has to wait at all when there are c parallel servers — the standard tool for sizing a trading desk's headcount, a market maker's quoting capacity, or a support team against a fluctuating arrival load.
Prerequisites: The Poisson Process, Queueing Theory and Birth-Death Processes
A trading desk's execution support line receives calls from traders needing manual order intervention, arriving randomly, and handled by a pool of staff, each taking a random amount of time per call. Management wants to know: with staff, what fraction of calls have to wait at all, rather than being answered immediately? Adding staff clearly helps, but by how much, and is there a point of sharply diminishing returns? This is the classic M/M/c queue — Poisson arrivals, exponential service times, parallel servers — and its answer, the Erlang C formula, is one of the oldest and most widely used results in applied probability, dating to early telephone exchange design and still governing staffing decisions today.
An analogy: checkout lanes at a grocery store
A single checkout lane gets overwhelmed quickly once the store gets even moderately busy, because there's no flexibility — one slow customer backs up everyone behind them. Add a second lane, and a slow customer in one lane doesn't block a fast one in the other; the two lanes absorb random bursts by having idle capacity elsewhere at any given moment. This is the core benefit of "pooling": parallel servers handling one combined queue is dramatically more efficient than separate single-server queues each handling its own slice of the load, because pooling lets servers cover for each other's random slow moments. The Erlang C formula quantifies exactly how much pooling helps.
The formula, one piece at a time
Let be the average arrival rate, be the average service rate per server, and be the number of parallel servers. Define the offered load (in "Erlangs" — the average number of servers that would be busy with infinite capacity) and the utilization (must be below 1 for the queue to be stable). The Erlang C formula gives the probability an arriving customer must wait (finds all servers busy):
In plain English: the numerator represents the "weight" of all states where every server is busy (customers queue up behind a full bank of servers), and the denominator normalizes it against every possible state, from empty system to fully saturated with a queue. The result is a single probability between 0 and 1 — how likely a random arrival is to face any wait at all before being served, purely as a function of the offered load and the number of servers .
Worked example 1: sizing the support desk
Suppose calls arrive at per hour and each staff member handles calls at per hour on average (about 20 minutes each), so offered load Erlangs. With staff, utilization is — dangerously close to saturation, and the Erlang C formula gives : 76% of calls wait. With staff, , and the formula drops to — adding just one more staff member (a 33% headcount increase) nearly halves the fraction of calls that wait at all, because utilization moved away from the steep, near-saturation part of the queueing curve.
Worked example 2: diminishing returns at c=6
Push further to staff with the same : utilization drops to , and falls to roughly 0.09 — only 9% of calls wait. Going from to (a 50% headcount increase) cut the wait probability from 44% to 9%, a large absolute drop, but the marginal benefit per extra staff member is now much smaller than the jump from to was — comparing gains, cut wait probability by 32 percentage points for 1 extra staff, while cut it by 35 points but needed 2 extra staff. This illustrates the general shape of Erlang C: wait probability falls steeply as moves away from the saturation boundary ( near 1), then flattens into diminishing returns once utilization is comfortably below it — telling a staffing manager roughly where "good enough" capacity lies.
What this means in practice
The Erlang C formula (and its refinements, like Erlang A which adds customer abandonment) underlies staffing decisions for any pooled-server system: execution support desks, market-making quoting engines that need enough parallel capacity to avoid queueing client orders, or cloud compute pools sized against a variable request rate. It's also directly relevant to understanding why pooling matters operationally — merging two separate, moderately-loaded queues into one combined queue with the same total server count structurally reduces average wait, without adding a single server, purely from the statistical smoothing pooling provides.
The Erlang C formula gives the probability an arriving customer must wait when parallel servers share one queue, as a function only of the offered load and ; wait probability falls steeply as moves away from the saturation point ( near 1) and flattens into diminishing returns once utilization is comfortably below it.
The classic mistake is running a queue at utilization close to 1 (server count barely above offered load) because it looks "efficient" on a naive cost-per-server basis, without recognizing that wait probability and average wait time both blow up sharply as under the Erlang C formula. A queue at 95% utilization isn't "5% away from perfect" — it's often already experiencing wait times many multiples of the average service time, because the formula's denominator behaves like , which explodes near .
Related concepts
Practice in interviews
Further reading
- Gross et al., Fundamentals of Queueing Theory, ch. 2
- Erlang, Post Office Electrical Engineers' Journal (1917)