Erlang C Explained for WFM Analysts
Every commercial workforce management tool, every staffing spreadsheet worth trusting, and every "how many agents do I need" argument eventually lands on the same hundred-year-old piece of math: Erlang C. Most WFM analysts use it daily through some tool's interface without ever seeing the machinery. This post opens the hood: what the model computes, how to read its formula without a math degree, a fully worked example, and, just as important, where it lies to you.
Where it came from and what it answers
Agner Krarup Erlang was a Danish engineer working for the Copenhagen Telephone Company in the early 1900s, trying to answer a hard capital question: how many trunk lines does an exchange need so that callers rarely encounter congestion? The model he published in 1917 for queued traffic is what we now call Erlang C, and it transfers to contact centers almost unchanged, because the problem is the same: random arrivals, service times that vary, a fixed pool of servers, and a queue when all servers are busy.
Erlang C answers one precise question: given an offered load and a number of agents, what is the probability that an arriving contact has to wait? From that single probability you can derive the two numbers operations leaders actually manage: service level (the share of contacts answered within a threshold, like 80 percent in 20 seconds) and average speed of answer (ASA).
Step one: offered load in erlangs
Everything starts with traffic intensity, written A and measured in erlangs:
- A = (contacts per interval × AHT in seconds) ÷ interval length in seconds
One erlang is one hour of workload per hour, equivalently, one continuously busy agent. Take 100 calls in a 30-minute interval at 300 seconds AHT: A = (100 × 300) ÷ 1800 = 16.7 erlangs. That is 16.7 agents' worth of pure talk-and-wrap work landing in the window, before anyone takes a break or the arrival pattern clumps.
The first hard rule of staffing math follows immediately: you need strictly more agents than erlangs. At N ≤ A the queue is mathematically unstable, it grows without bound. Staffing 17 agents against 16.7 erlangs is technically stable and practically a death spiral, which brings us to the formula.
The formula, in plain language
Erlang C computes the probability of waiting, P(wait), from A and the number of agents N. Written out in words rather than symbols: take A to the power of N divided by N factorial (the "all servers busy" weight), and divide it by that same quantity plus a correction term, (1 − A/N) times the sum over k from 0 to N−1 of A to the k divided by k factorial, which weights all the states where a free agent exists.
You will never compute that by hand, and you do not need to; spreadsheets and calculators iterate it in milliseconds. What you should internalize is what follows from P(wait):
- Service level = 1 − P(wait) × e^(−(N − A) × T ÷ AHT), where T is your answer threshold in seconds.
- ASA = P(wait) × AHT ÷ (N − A).
Both formulas are governed by the term (N − A): the cushion of agents above the offered load. Service quality is bought entirely with that cushion, and the purchase is nonlinear.
A worked example, and the nonlinearity that runs your floor
Stay with A = 16.7 erlangs (100 calls per half hour, 300-second AHT), targeting 80 percent answered in 20 seconds:
- At 18 agents, the cushion is 1.3 agents. P(wait) is high, ASA lands around four minutes, service level is dismal. Technically stable, operationally on fire.
- At 20 agents, things improve sharply: service level climbs to roughly 73 percent, ASA falls to around 35 seconds.
- At 21 agents, service level reaches about 83 percent with ASA near 16 seconds: target met.
- At 23 agents, service level is around 94 percent, and each further agent buys less than the one before.
Read that ladder again: between 20 and 21 agents, one person moved service level nearly ten points. That cliff-edge behavior is the single most important thing Erlang C teaches. It is why being "only two agents short" can melt a queue, why overtime offered to three people can rescue an afternoon, and why interval-level coverage tracking matters so much: the damage of a small shortfall is wildly out of proportion to its size. You can explore the cliff yourself with our free Erlang C calculator, change the inputs and watch the outputs jump.
From productive agents to scheduled agents
Erlang C's answer, 21 in our example, is productive bodies on the queue. Real schedules must supply humans who take breaks, attend meetings, get sick, and sit in training. That conversion is the shrinkage gross-up:
- Scheduled agents = Erlang answer ÷ (1 − shrinkage)
At a typical 30 percent shrinkage, 21 productive agents means scheduling 30. Skipping this step is the most common catastrophic staffing error; the second most common is planning at 100 percent occupancy. Check the occupancy the model implies, A ÷ N, and cap it: at 21 agents on 16.7 erlangs, occupancy is 79 percent, which is sustainable. If your service level target is somehow met at 95 percent occupancy, add agents anyway; humans cannot run at 95 percent for a shift, and AHT and attrition will collect the debt. (More on that distinction in our occupancy versus utilization post.)
Where Erlang C lies to you
The model rests on assumptions that real contact centers violate daily. Knowing the direction of each error matters more than the magnitude:
- No abandonment. Erlang C assumes every caller waits forever. Real callers hang up, which thins the queue, so in high-abandonment centers the model overstaffs slightly relative to observed service level. (Erlang A models abandonment explicitly; Erlang C remains the conservative planning standard.)
- Smooth random arrivals. The model assumes Poisson arrivals. Real volume arrives in bursts, the marketing email lands, the outage tweet spreads, and burstier-than-Poisson arrivals mean the model understaffs the spiky intervals.
- One skill, one queue. Multi-skill routing, overflow rules, and chat concurrency all break the single-pool assumption. Multi-skill efficiency means a naive per-queue Erlang sum overstates total need somewhat.
- Steady state within the interval. The model assumes the interval is long enough to settle. A 15-minute interval with a spike in minute two never settles.
The practical posture: Erlang C is an excellent planning baseline and a poor autopilot. Use it to set the interval requirement, then watch reality against the plan and correct intraday. That division of labor is exactly how QueuePilot is built: the Forecast Lab runs Erlang-style requirements with shrinkage and occupancy guardrails per interval, and the Intraday Copilot watches live variance, the abandonment, the bursts, the call-outs the formula cannot see, and recommends corrections while there is still time to act.
What to remember
- Offered load A = volume × AHT ÷ interval length, in erlangs; you must staff above it.
- Service quality is bought with the cushion N − A, and the purchase is sharply nonlinear: near the target, one agent moves service level by whole points.
- Erlang's answer is productive agents; divide by (1 − shrinkage) to get scheduled agents, and check implied occupancy.
- The model ignores abandonment and bursts: trust it for planning, verify it intraday.
A century on, the math still holds. The teams that get hurt by Erlang C are not the ones using it, they are the ones using it without knowing what it assumes.