Erlang C, explained for planners
What the formula actually does, the four assumptions it makes on your behalf, why it runs in two directions, and why your vendor’s “proprietary staffing algorithm” is almost certainly this with a different label on it.
Most planners meet Erlang C as a black box. You put volume and handle time into a tool, a number comes out, and the number is either accepted or argued with depending on how the last quarter went. That is a bad position to be in, because the number is frequently wrong in ways that are entirely predictable once you know what the formula assumes.
This is the explanation, not the calculator. If you want to put your own interval in and get an answer, use the free Erlang C calculator; it shows every step. What follows is why those steps are what they are.
The one input that matters: offered load
Erlang C does not care how many contacts you get. It cares about offered load, the number of contacts multiplied by how long each one takes, divided by the length of the interval. The unit is the Erlang, and one Erlang means “one agent’s worth of continuous work”.
250 contacts in a 30-minute interval at 240 seconds AHT is 33.33 Erlangs. That is the entire demand signal. A center taking 250 contacts at 240 seconds and a center taking 500 contacts at 120 seconds are, to this formula, identical.
This is why AHT drift is so much more dangerous than volume drift, and so much less watched. Volume moving 10% and AHT moving 10% do exactly the same thing to your requirement, but only one of them gets a daily meeting.
The four assumptions, and what each one costs you
Erlang C is a queueing model from 1917, built by A. K. Erlang for telephone exchanges. It buys its tractability with four assumptions. Every one of them is false in a real contact center; the question is only whether it is false enough to matter for your queue.
- Nobody abandons. Callers wait forever, patiently, until answered. Real callers hang up, and every abandoned call is demand that left the queue without consuming an agent. On queues with meaningful abandonment, Erlang C therefore overstaffs. This is the single biggest source of “the model says 40 but we run fine on 35”.
- Arrivals are random and stable within the interval. Poisson arrivals, flat rate across the whole interval. A queue that takes 90% of its half-hour in the first eight minutes (a marketing send, a system outage, a school run) is not this. The model will understate what you need at the peak inside the interval.
- One homogeneous pool. Every agent can take every contact and takes exactly the same time doing it. The moment you have genuine skills-based routing across non-interchangeable pools, running one Erlang C over the whole headcount is arithmetic, not planning.
- No blocking, infinite queue. Nobody gets a busy tone. Fine for most modern platforms, occasionally not for voice with hard trunk limits.
None of this makes Erlang C useless. It makes it a default rather than a universal. The failure mode in the industry is not using it. It is using it without ever writing down which of these four assumptions your queue actually violates.
The formula runs in two directions
This is the part most tools hide, and it is the part that makes Erlang C useful for arguments rather than just for rosters.
Forward takes agents and gives you service. I have 39 people on this interval, what am I going to deliver? Backward (or inverse) takes a service target and gives you agents. I need 80% answered in 20 seconds, how many people?
There is no closed-form solution to the backward direction. You cannot rearrange the equation for N. Every WFM tool on the market solves it the same way: it runs the forward calculation repeatedly, incrementing headcount, until the target is met. That is the whole trick.
Worked: forward
Same interval throughout: 250 contacts, 30 minutes, 240s AHT, and we ask what various headcounts deliver against an 80%-in-20-seconds target.
| Agents | Service level | ASA | Occupancy | Chance of waiting |
|---|---|---|---|---|
| 38 | 77.4% | 17.1s | 87.7% | 33.3% |
| 39 | 84.2% | 10.8s | 85.5% | 25.4% |
| 40 | 89.1% | 6.9s | 83.3% | 19.1% |
| 42 | 95.0% | 2.8s | 79.4% | 10.3% |
| 45 | 98.6% | 0.7s | 74.1% | 3.6% |
| 50 | 99.9% | 0.1s | 66.7% | 0.5% |
Look at what one agent does at the bottom of that table. Going from 38 to 39 (a single person) moves service level 6.8 points and cuts average speed of answer by more than a third. Going from 45 to 50 (five people) buys 1.3 points.
That is the most important practical fact about Erlang C and the reason intraday decisions feel so erratic to people outside the planning team. Near the edge, one agent is enormous. Comfortably above it, five agents are almost nothing. Any conversation about “can we pull two people for training” that does not start with where the interval sits on this curve is guesswork.
Worked: backward
Same interval, now asking for 80/20 with an 85% occupancy ceiling:
- Offered load A = 33.33 Erlangs
- Smallest headcount meeting 80/20: 39 agents (84.2% service level)
- But 39 agents puts occupancy at 85.5%, over the cap
- Smallest headcount meeting the cap: 40 agents
- Requirement is the larger of the two: 40 agents, and the binding constraint is the occupancy cap, not service level
- At 30% shrinkage, rostered requirement is 40 ÷ 0.70 = 57.1 FTE
What the occupancy cap actually does
Occupancy is offered load divided by agents, the share of productive time your people spend actually handling contacts. It is the one number in this system that gets better as you add staff, which is why it behaves so counter-intuitively as a constraint.
In the example above, the cap was the binding constraint. Service level was satisfied at 39; the cap forced 40. Most tools will report “40 agents required” and stop there, which is how planners end up unable to answer the obvious follow-up question: why 40 and not 39? The honest answer, “service level was fine at 39, but it would have run your people at 85.5% and we cap at 85”, is a completely different conversation with an ops director than “the system says 40”.
Sustained occupancy north of roughly 85% is well established as an attrition driver. The cap is not a comfort setting. On busy intervals it is frequently the real constraint, and if your tool cannot tell you when that is the case, you are flying with an instrument missing.
Why bigger centers look more efficient (and it isn’t management)
Run the backward calculation at the same AHT and the same target across different volumes, and the agents-per-contact ratio falls as the center gets bigger:
| Contacts / 30 min | Offered load | Agents for 80/20 | Occupancy | Agents per 100 contacts |
|---|---|---|---|---|
| 125 | 16.67 E | 21 | 79.4% | 16.80 |
| 250 | 33.33 E | 39 | 85.5% | 15.60 |
| 500 | 66.67 E | 74 | 90.1% | 14.80 |
| 1,000 | 133.33 E | 142 | 93.9% | 14.20 |
Volume goes up eightfold; headcount goes up under seven-fold. This is a real, structural economy of scale and it has two consequences worth internalising.
First, pooling is worth money. Two queues of 125 need 42 agents between them; one queue of 250 needs 39. If those queues are genuinely interchangeable, keeping them separate costs you three heads per interval for no service benefit. That is the entire quantitative case for multi-skilling, and it is why fragmenting a small operation into many small skill groups is so expensive.
Second, and less comfortably: the same table shows occupancy climbing to 93.9% at the top. Large queues hit service targets at brutal occupancy. Without a cap, the “efficiency” of scale is partly just a burnout schedule dressed up as a staffing plan.
Why your vendor’s proprietary algorithm is probably this
Erlang C is 108 years old and unpatentable. When a WFM vendor declines to say what their engine does, the realistic possibilities are: Erlang C; Erlang C with an abandonment adjustment (Erlang A); Erlang C with some smoothing on the inputs; or a simulation, which is a genuine and meaningfully different choice that vendors who have built one tend to advertise loudly, because it is expensive.
The differentiator worth asking about is not the formula. It is whether the tool will show you the working: the offered load it derived, the headcount it tested, which constraint bound, and what shrinkage assumption it applied. A requirement you cannot reconstruct is a requirement you cannot defend in a headcount review six weeks later, and defending it is most of the job.
Three questions that separate tools quickly:
- “Show me why this interval says 40 and not 39.” If nothing in the product answers that, the model is a black box regardless of what is inside it.
- “Where is shrinkage applied?” It belongs outside the queueing maths. Inside it, it double-counts. See the shrinkage article for what that error costs.
- “What happens when offered load exceeds headcount?” The formula has no answer there: the queue is mathematically unstable. Tools that silently return a plausible-looking number in that situation are hiding the most important thing they know.
When to stop using it
- Real abandonment. Use Erlang A, which models caller patience. Erlang C will overstaff you.
- Email, tickets, back office. Work that carries between intervals is a workload problem, not a queueing one. Erlang C answers a question you are not asking.
- Chat with concurrency. An agent handling three chats is not three agents, and it is not one either. Model effective capacity first, then queue it.
- Spiky arrivals inside the interval. Shorten the interval before you distrust the formula; 15 minutes often fixes what looked like a model failure.
- Genuinely separate skill pools. Calculate per pool. One Erlang C over a headcount that cannot actually serve every contact is a number with no meaning.
The short version
Erlang C converts a demand signal into a headcount by assuming a well-behaved queue, and it does so non-linearly: the value of one more agent depends entirely on where you already are. Use it as a default, know which of its four assumptions your queue breaks, apply shrinkage outside it, cap occupancy, and insist on seeing the working. Everything else is labelling.
Every number in this article came out of a calculator you can use.
The free Erlang C calculator runs the same engine as the SureWFM platform: same recursion, same search order, same occupancy and shrinkage handling. It shows the decision curve, tells you which constraint bound, and does not ask for your email.
Related: where shrinkage belongs · running an intraday loop