Operations
Erlang C for people who hate maths: how many agents a phone queue actually needs
- 13 min read
By Sujan ThapaliyaLast updated
The short answer
Every contact centre eventually asks the same question, and almost always answers it wrong: how many people do we need on the phones? The instinctive answer is to divide the calls by what one person can handle. That answer is not merely imprecise — it is structurally wrong, and it is wrong in a direction that guarantees a queue nobody can dig out of.
The right answer comes from a formula an engineer at the Copenhagen Telephone Company worked out in 1917, while trying to decide how many physical circuits a switchboard needed. It is still the formula, and the unit of traffic is still named after him. This piece explains it without assuming you want to look at it, and then shows two results from it that change how a roster gets built.
How many agents do I need to answer calls?
Take a concrete queue and stay with it for the rest of the article: 180 calls an hour, and an average handle time of 240 seconds — four minutes of talking and wrapping up per call. The target is the industry-standard one, 80% of calls answered within 20 seconds, usually written 80/20.
The naïve calculation: one agent handles 3,600 ÷ 240 = 15 calls an hour, so 180 ÷ 15 = 12 agents. That number is not the staffing requirement. It is the point at which the queue becomes mathematically unstable — where agents are busy 100% of the time, nobody is ever free at the moment a call lands, and the queue grows for as long as the calls keep coming.
12
erlangs of traffic offered
12
agents the naïve division gives
16
agents actually needed for 80/20
75%
occupancy at that staffing
The real answer is 16. The four extra agents are not slack in the roster; they are the reason the queue clears. Understanding why is the whole subject.
What is an erlang, and why is a queue not just division?
An erlang is one hour of work arriving per hour — a single line kept busy continuously. Our queue offers 180 calls at 240 seconds each, which is 43,200 seconds of work per hour, or 12 erlangs. The unit is deliberately dimensionless in time: it is the load, not a headcount.
traffic (erlangs) = calls per hour × average handle time in seconds ÷ 3,600
12 = 180 × 240 ÷ 3600Division fails because calls do not arrive politely spaced. They arrive at random, which means that in any given minute several may land at once while the next minute is silent. The agent who is free in the quiet minute cannot be saved up and spent during the busy one. Every queue therefore needs capacity that is idle most of the time, purely to absorb the moments when arrivals cluster.
Idle agents are not waste. They are the mechanism by which a queue absorbs randomness — and the only alternative to a queue that never clears.
Erlang C prices that randomness. It gives the probability that a call arrives to find every agent busy, and from there the share answered inside any target time. The average speed of answer and occupancy fall out of the same calculation.
The formula, for the two people who want it
Why does one more agent change service level so much?
This is the result that makes workforce planning counter-intuitive. Service level is not proportional to headcount. Near the unstable point it is almost vertical, and once the target is met it flattens out into a plateau where extra agents buy almost nothing.
| Agents | Answered in 20s | Average speed of answer | Occupancy |
|---|---|---|---|
| 12 | 0% | never clears | 100% |
| 13 | 35.2% | 169s | 92.3% |
| 14 | 59.2% | 58s | 85.7% |
| 15 | 75.1% | 26s | 80.0% |
| 16 | 85.3% | 12s | 75.0% |
| 17 | 91.7% | 6s | 70.6% |
| 18 | 95.4% | 3s | 66.7% |
| 19 | 97.6% | 1s | 63.2% |
| 20 | 98.8% | 1s | 60.0% |
Read the table twice. Going from 13 agents to 14 buys 24 points of service level and cuts the wait by nearly two minutes. Going from 19 to 20 buys 1.2 points and cuts the wait by nothing measurable. Those are the same agent, at the same salary, producing wildly different returns.
The practical consequences run in both directions. A queue sitting just below target is one person away from fixing it, which is the cheapest service-level improvement available anywhere in the operation. A queue comfortably above target is carrying agents who cost full price and deliver a rounding error — and who could hold a second skill, take outbound work between calls, or simply not be rostered.
It also explains the failure mode every centre knows and few can articulate: the day two people call in sick and the whole afternoon collapses. Nothing gradual happened. The queue crossed the steep part of that curve.
Occupancy above 85% is not efficiency
Why does a bigger queue need fewer agents per call?
Randomness averages out at scale, so the buffer a queue needs grows more slowly than the traffic does. This is the closest thing to a free lunch in contact-centre operations, and it is why consolidating queues usually beats optimising them.
| Calls/hour | Erlangs | Agents needed | Occupancy | Agents per erlang |
|---|---|---|---|---|
| 45 | 3 | 5 | 60.0% | 1.67 |
| 90 | 6 | 9 | 66.7% | 1.50 |
| 180 | 12 | 16 | 75.0% | 1.33 |
| 360 | 24 | 29 | 82.8% | 1.21 |
| 720 | 48 | 54 | 88.9% | 1.12 |
| 1,440 | 96 | 104 | 92.3% | 1.08 |
Sixteen times the calls needs only 6.5 times the agents. A small queue spends two-thirds of an agent per erlang on absorbing randomness; a large one spends less than a tenth.
The operational reading is that splitting a queue is expensive in a way that never appears on a budget line. Four separate five-agent queues, each handling 45 calls an hour, need 20 agents. One 20-agent queue handling all 180 needs 16 — the same service level, four fewer people, purely from not having partitioned the traffic. Every skill-based routing rule that carves the queue into segments is spending some of that, and it is worth knowing what it costs before adding another one.
It also cuts the other way, and this is the part that catches growing teams. Because large queues run at high occupancy by design, they have proportionally less slack. The 104-agent queue is at 92.3% occupancy — it is efficient precisely because it is close to the edge, and it has correspondingly less absorption when an unexpected spike arrives.
Why staffing to a daily average fails at the same cost
This is the result worth taking to a planning meeting. Take a day of 1,440 calls spread across eight hours, and compute the requirement two ways: hour by hour against the actual profile, or once against the daily average of 180 calls an hour.
| Hour | Calls | Erlangs | Agents for 80/20 |
|---|---|---|---|
| 09:00 | 120 | 8 | 11 |
| 10:00 | 210 | 14 | 18 |
| 11:00 | 300 | 20 | 25 |
| 12:00 | 180 | 12 | 16 |
| 13:00 | 150 | 10 | 14 |
| 14:00 | 240 | 16 | 20 |
| 15:00 | 150 | 10 | 14 |
| 16:00 | 90 | 6 | 9 |
Staffing to the daily average instead means 16 agents for eight hours: 128 agent-hours, against the 127 the interval calculation asks for. The flat roster is not cheaper. It costs marginally more, and it is easier to build, which is exactly why it gets built.
Then look at 11:00. That hour offers 20 erlangs and has 16 agents. Sixteen is below twenty, which means the queue is unstable for the entire hour: work arrives faster than it can be served, the backlog grows continuously, and the model returns a service level of zero because there is no steady state to compute. In the real world callers give up instead, so what actually happens is an hour of near-total abandonment followed by an afternoon of callbacks that never appeared in anyone's forecast.
The flat roster and the interval roster cost the same 128 agent-hours. One of them hits target all day. The other loses an hour every day, in the same place, forever.
This is the single most valuable thing Erlang C tells you, and it has nothing to do with the formula's precision. Staffing requirement is not additive across time. You cannot average a day, a week or a campaign and staff to the result, because the average hour does not exist — and the ITU makes the same point about traffic measurement generally, which is read over short intervals rather than smoothed. Half-hour intervals are the usual planning grain, and hourly is the coarsest that is still honest.
What does shrinkage do to the answer?
Everything above computes agents *on the phones*, at that moment. It is not a headcount. The gap between the two is shrinkage: breaks, training, meetings, coaching, sickness, holiday, and the general fact that a paid hour is not an available hour.
| Shrinkage | Roster required | Rounded up |
|---|---|---|
| 0% | 16.0 | 16 |
| 10% | 17.8 | 18 |
| 20% | 20.0 | 20 |
| 30% | 22.9 | 23 |
| 35% | 24.6 | 25 |
| 40% | 26.7 | 27 |
At the 30–35% shrinkage most centres actually run, the 16-agent requirement is a 23–25 person roster. Divide by the requirement rather than multiplying by the shrinkage percentage: 16 ÷ 0.70 is 22.9, whereas 16 × 1.30 is 20.8, and the second answer is short by two people. It is a common enough slip to be worth stating twice.
What happens when handle time moves?
Handle time enters the traffic calculation linearly, so it deserves as much attention as volume — and unlike volume, it is something the operation controls.
| Average handle time | Erlangs | Agents needed |
|---|---|---|
| 150s | 7.5 | 11 |
| 180s | 9.0 | 12 |
| 210s | 10.5 | 14 |
| 240s | 12.0 | 16 |
| 270s | 13.5 | 18 |
| 300s | 15.0 | 19 |
| 360s | 18.0 | 23 |
Thirty seconds of average handle time is worth about two agents on this queue. That is the honest business case for anything that shortens a call without damaging it: better screen-pop, fewer transfers, a knowledge base that answers the top ten questions, or wrap-up work that happens during the call rather than after it.
The caution is that handle time is the easiest metric in the building to game, and the damage does not show up in this table. A call cut short becomes a call made again tomorrow, which raises volume — and volume enters the same formula. Track it beside first-contact resolution or the improvement is imaginary. The wider version of this argument is in call centre metrics that actually change decisions.
Where Erlang C is wrong
The formula assumes several things that are not true of any real queue. None of them make it useless; all of them determine which direction its error runs.
- Nobody hangs up. Erlang C assumes infinite patience, so every caller waits as long as it takes. Real callers abandon, which relieves the queue — so the model overstates the agents needed on a badly performing queue, sometimes substantially. Models that include abandonment (Erlang A, and simulation) exist for exactly this.
- Nobody calls back. An abandoned caller who redials becomes new traffic the forecast never counted, and it lands during the peak that caused the abandonment.
- Arrivals are random and steady within the interval. Calls following a broadcast, an email send or an outage do not behave this way at all; they arrive in a spike no smooth model describes.
- Every agent is identical and every call is the same. Multi-skill routing breaks the single-queue assumption, and the honest tool there is simulation rather than a closed-form formula.
- The interval is independent. In reality a backlog spills into the next interval, which is why an under-staffed 11:00 damages 12:00 as well.
Used as a planning instrument rather than a prophecy, it remains the right default. It is directionally correct, it is computable on any laptop, it takes two inputs a centre already measures, and its errors are understood. Compare that to the alternative in most rosters, which is a number somebody once felt was about right.
Does any of this apply to outbound?
Not directly, and it is worth being explicit because the vocabulary collides. Erlang C describes an inbound queue where work arrives and agents wait. Outbound inverts it: agents wait and the dialler manufactures the work, so the pacing engine sets the arrival rate rather than observing it.
What survives the crossing is the shape of the problem. Call pacing is dimensioning under uncertainty in exactly the same sense, with the same steepness near the limit, and the same penalty for treating an average as a plan. The difference is the constraint: an inbound queue that overshoots makes callers wait, whereas an outbound campaign that overshoots drops live answers, and those are capped by regulation at 3% — see abandonment rate for how that one is measured and why the denominator is so often got wrong.
Blended operations get the hard version of both. Inbound demand is stochastic and must be answered; outbound work is elastic and can absorb the gaps. Running them from one pool is genuinely more efficient than running two — the scale-economy table above is why — but only if the pacing engine treats inbound occupancy as an input in real time rather than as a daily assumption. That is a property of the cloud call centre platform doing the routing, not of the roster.
Reproducing this
Frequently asked questions
How many agents do I need for 100 calls per hour?
What is the Erlang C formula?
Why does Erlang C need more agents than calls divided by capacity?
What interval should I calculate staffing over?
Is 100% occupancy the goal?
Does Erlang C work for chat, email or outbound calling?
Should I account for callers who hang up while waiting?
Sources
- ITU-T Recommendation E.520 — Number of circuits to be provided in automatic and/or semiautomatic operation, without overflow facilities — International Telecommunication UnionDimensioning a group of servers against offered traffic and a target grade of service — the standards-body statement of the problem Erlang C is used to solve.
- ITU-T Recommendation E.500 — Traffic intensity measurement principles — International Telecommunication UnionTraffic intensity measured in erlangs, and the principle that it is read over short measurement intervals rather than averaged across a day.
- ITU-T Recommendation E.501 — Estimation of traffic offered in the network — International Telecommunication UnionEstimating offered traffic from carried traffic, and why offered load is the quantity a staffing calculation needs.
See it working: cloud call centre
Cloud call centre software runs your inbound and outbound phone operation from a browser: queues, routing, dialling, recording, and reporting, with no on-premise hardware. AI Dialer prices it by usage rather than per seat, so cost tracks call volume instead of headcount.
- No subscription
- Numbers in 100+ countries
- Compliance built in