A.K. Erlang published his queuing formula in 1917 to figure out how many telephone circuits the Copenhagen Telephone Company needed. Over a century later, call center managers still plug three numbers into an Erlang C calculator from a website that looks like it was built in 2003, get a number, and treat it as staffing truth. Then they wonder why Monday at 9 AM has a 12-minute wait time and Thursday at 2 PM has six idle agents.
The Erlang C formula is real math. It's correct math. It just answers the wrong question for a real call center. Here's what it assumes: calls arrive randomly (Poisson distribution), all agents are identical and interchangeable, no callers abandon, agents handle one call then immediately take the next, call arrival rate is constant, there's no wrap-up time between calls, and nobody takes breaks, calls in sick, or goes to lunch. Exactly zero of these assumptions hold in practice.
But Erlang C is still where you start, because it gives you the mathematical floor — the minimum agents you'd need in a universe where everything works perfectly. Then you adjust for the real world, and the adjustment is where 95% of people stop too early.
The Gap Is Always 27-57%
After running staffing models across dozens of operations, the gap between what Erlang C says and what you actually need is remarkably consistent:
| Scenario | Calls/30min | AHT | Erlang C Says | You Actually Need | Gap |
|---|---|---|---|---|---|
| Small inbound support | 30 | 300s | 7 | 9-10 | +29-43% |
| Medium sales inbound | 80 | 240s | 14 | 18-20 | +29-43% |
| Large blended center | 200 | 210s | 26 | 33-37 | +27-42% |
| Collections floor | 50 | 180s | 7 | 9-11 | +29-57% |
| High-touch B2B sales | 25 | 600s | 11 | 14-16 | +27-45% |
That gap isn't noise. It's the accumulated weight of four factors that Erlang C completely ignores.
Factor 1: Shrinkage (25-35%)
Shrinkage is the percentage of paid time agents are unavailable to handle calls. Breaks (30 min/day), lunch (30-60 min/day), training and meetings (2-4 hours/week), coaching sessions, system issues (frozen computer, VPN dropout, softphone crash), unscheduled absences, late arrivals, and early departures.
The industry average is 30-35% for on-site centers and 35-40% for remote agents (home distractions, internet issues, longer breaks). Most operations discover their actual shrinkage is higher than they assumed.
The adjustment is simple: Adjusted agents = Erlang C agents / (1 - shrinkage_rate). If Erlang C says 19 and your shrinkage is 32%: 19 / 0.68 = 28 agents. Already a 47% increase from the raw number.
Factor 2: Occupancy Limits
Occupancy is the percentage of time an agent spends on calls versus waiting. At 84% occupancy, agents spend 50 minutes of every hour on the phone. That sounds efficient. It's also a fast track to burnout. Sustainable occupancy depends on the work:
- Inbound support (simple): 85-88%
- Inbound sales: 78-82%
- Outbound cold calling: 75-80%
- Collections: 72-78%
If your staffing model produces 90%+ occupancy, expect a turnover problem within 60 days. Agents start calling in sick, taking longer breaks, and quitting. Replacing one agent costs $3,000-8,000 in recruiting, training, and ramp-up time. Running agents at 90% to save on staffing is one of the most expensive mistakes a call center can make.
Factor 3: Call Abandonment
Erlang C assumes callers wait forever. They don't. 25% hang up after 30 seconds, 50% after 60 seconds, 70% after 120 seconds. This creates a vicious paradox: understaffing causes abandonments, which reduce apparent call volume, which makes Erlang C tell you that you need fewer agents. The formula rewards you for bad service.
The fix: add abandoned calls back into your volume calculation. Use total calls offered (answered + abandoned) as your input, not just answered calls. If any half-hour interval shows an abandon rate above 5%, that interval is understaffed. Period.
Factor 4: Multi-Skill Routing
If agents handle multiple queues (billing, sales, tech support), Erlang C breaks down. The formula assumes perfect pooling — all agents interchangeable. In reality, Agent A handles billing and sales, Agent B handles sales only, Agent C handles all three. This partial pooling is more efficient than separate queues but less efficient than the full pooling Erlang C assumes. Expect an 8-15% underestimate for multi-skill environments.
The Real Formula
Required staff = (Erlang_C_agents * (1 + multi_skill_factor)) /
(1 - shrinkage_rate) /
min(target_occupancy, 1.0) *
(1 + absenteeism_buffer)
For 120 calls per half-hour with 240-second AHT, 80/20 service level:
Erlang C raw: 19 agents
+ Multi-skill (10%): 20.9 agents
+ Shrinkage (32%): 30.7 agents
+ Occupancy (82%): 37.5 agents
+ Absenteeism (5%): 40 agents
Forty agents to do what Erlang C says you can do with nineteen. A 111% gap. And forty is the right number — anyone who's run a 120-call-per-half-hour inbound operation knows that 19 agents would result in 15-minute hold times and mass abandonment.
Half-Hour Grids and Day-of-Week Adjustment
Your call volume isn't flat. It spikes in the morning, dips at lunch, picks up in the afternoon. You need a staffing grid that calculates required agents for each 30-minute interval using your actual historical volume data.
Practical moves that make the grid work:
Stagger start times. If you need 25 agents at 8 AM and 40 at 9:30 AM, don't have everyone clock in at 8. Bring them in waves — 5 at 7:00, 5 at 7:30, 10 at 8:00, 5 at 8:30, 10 at 9:00, 5 at 9:30.
Stagger lunches. Split 40 agents into 4 groups at 11:00, 11:30, 12:00, and 12:30. You lose 10 agents during each lunch slot instead of 40. This alone can drop your midday abandon rate by 60%.
Build separate grids for each day. Monday volumes are typically 15-25% higher than Friday. Using one staffing plan for every day means overstaffed on Friday and drowning on Monday.
Validate weekly. Compare your model's predicted service level for each interval against what actually happened. If you're off by more than 10%, recalibrate your shrinkage rate and AHT assumptions.
Outbound Is Different Math
Outbound staffing follows different rules because the dialer controls the pace. The key formula:
calls_per_agent_per_hour = 3600 / (avg_talk_sec + avg_wrapup_sec + avg_ring_sec / connect_rate)
required_agents = target_contacts_per_hour / calls_per_agent_per_hour
For B2B outbound with 10% connect rate, 180-second talk time, 30-second wrap-up: 7.8 contacts per agent per hour. Need 60 contacts per hour? That's 8 productive agents, or 12 scheduled after shrinkage. If you need 300 contacts per day across an 8-hour shift, you need about 5 productive agents, which means 8 scheduled.
For blended campaigns (agents taking inbound and making outbound between calls), calculate the inbound staffing need first — that's the hard constraint. Then figure out how much outbound capacity exists in the gaps. Don't try to optimize both simultaneously in one formula. Calculate them separately and overlay the results.
Common Mistakes That Blow Up Staffing Models
Using daily averages instead of half-hour intervals. If your average daily call volume is 800, you might calculate that you need 25 agents. But if 200 of those 800 calls come between 9:00 and 10:00 AM, you need 40 agents during that hour and 15 the rest of the day. Daily averages hide the peaks that destroy your service level.
Ignoring AHT variance by agent. Your average AHT is 240 seconds, but Agent A averages 180 and Agent B averages 380. If Agent B is scheduled during peak hours and Agent A is on the quiet shift, your actual service level during peak will be much worse than the model predicts. Match your best agents (lowest AHT, highest conversion) to your highest-volume intervals.
Not accounting for new agent ramp-up. New agents typically have AHTs 40-80% higher than tenured agents during their first 30 days. If you're onboarding 5 new agents and counting them as full-capacity resources, you're overstating your actual handling capacity.
Treating blended campaigns like pure inbound. In a blended VICIdial environment, the moment inbound volume spikes, agents get pulled from outbound, the dial level drops, and your outbound throughput craters. Model the inbound constraint first, then figure out how much outbound capacity remains in the gaps.
Forgetting that breaks cluster. You schedule 15-minute breaks at 10:00 and 10:15 in two groups. But five agents take their break 8 minutes late, three come back 4 minutes late, and one disappears for 22 minutes. Your "planned" 15-minute break actually removes agents for 25-30 minutes. Build a 50% buffer on scheduled break durations.
Using answered calls instead of offered calls as input. If callers are abandoning because of long wait times, the answered volume is artificially low. Erlang C tells you that you need fewer agents based on this suppressed volume. Use total offered calls (answered + abandoned) to avoid the negative feedback loop.
The Bottom Line
The operations that get staffing right aren't the ones with the best formula. They're the ones that measure, compare, adjust, and repeat. Every week, forever. Pull last week's actual volume, AHT, and service level by half-hour. Compare to your model. If the gap is more than 10%, update your assumptions. Run a two-week forecast. Recalibrate your baseline shrinkage percentage monthly from actual data.
Erlang C is a starting point. The real work is everything you layer on top and the discipline to keep your inputs fresh. A call center that gets staffing right — not once, but every week — runs at lower cost with better service levels than one that throws bodies at problems. The math isn't hard. The discipline to keep updating your inputs is the hard part.
The difference between 80/20 and 90/10 service level targets can be 30-40% more agents for the same volume. That's not a typo. The relationship between service level and staffing is exponential, not linear. Make sure your target actually matches your business needs before you build a model around it — a lot of operations run 80/20 by default because "that's the industry standard" without ever asking whether their customers would be fine with 80/30.
For the complete implementation with Python Erlang C solver code, SQL queries for extracting AHT, shrinkage, and volume from VICIdial, half-hour staffing grid generators, and automated weekly validation scripts, see the full guide at ViciStack.
Top comments (0)