Workforce Optimisation via Erlang C and Automated Schedule Modelling
How I transitioned a 44-FTE L1 service desk from 24/7 to 7AM-8PM by building a schedule matrix in Excel - with Erlang C driving the staffing floors and automated break and lunch constraints enforced across every 30-minute slot.
Contract
L'Oréal
L1 Tech Support
Team size
44 FTEs
Level 1 agents
Benchmark AHT
15 min
incl. wrap-up, 10% above 6-mo avg
Lunch batches
10 + 10
max per slot at 12:00 and 13:00
The Challenge
The L'Oréal service desk contract had been running 24/7 with 44 Level 1 Tech Support agents. The business decision came through: move to 7AM-8PM, seven days a week. The overnight window - midnight to 7AM - was carrying less than 7% of total weekly call volume but the full cost of night-shift premium pay.
The problem handed to me: distribute 44 FTEs across a 13-hour operational day, maintain contractual SLAs, and keep the roster manageable. The existing schedule system used lettered codes - each representing a specific start time and shift window, spaced every 30 minutes. There were a lot of them.
The hard part wasn't just staffing numbers. It was ensuring that break and lunch windows - which in a 44-person team happen all day long - never pulled enough agents off the phones simultaneously to break the SLA. That needed to be automated, not eyeballed.
The Approach
What is Erlang C?
Erlang C is a telephony traffic model developed by Danish engineer A.K. Erlang. Given call arrival rate (λ), average handle time (AHT), and number of agents (N), it computes the probability that an arriving call will queue. From that probability you derive the service level: the percentage of calls answered within a target wait time.
Applied per 30-minute slot across the full operational window using a 15-minute benchmark AHT (6-month rolling average +10%, inclusive of wrap-up time), this produced the minimum agents that must be actively on the phones at every moment. That number became the hard constraint the schedule matrix had to satisfy.
Call data at 30-min granularity
Pulled historical call arrival data at 30-minute intervals - not hourly. The difference matters: a peak that looks flat at the hour level can hide a sharp 30-minute spike that breaks SLA. This data drove the Erlang inputs for every slot across the day.
AHT profiling - with a deliberate buffer
Calculated average handle time over the last 6 months for the L'Oréal L1 queue, including the wrap-up period (post-call work that ties up an agent just as much as the call itself). The benchmark AHT used in all Erlang calculations was then set 10% above that rolling average. Building in a buffer means the model stays valid even on slightly worse-than-average days, without needing to be rebuilt constantly.
Erlang C per slot
Ran Erlang C for every 30-minute slot from 07:00 to 20:00. Output: the minimum number of agents that must be actively available (not on break or lunch) to hit the SLA target. This became the non-negotiable floor the schedule matrix had to stay above.
Build the schedule matrix
The schedule system used letter-number codes (A1, B1, B2, etc.), each representing a fixed shift window with a start time every 30 minutes. One schedule opens at 6AM with a minimum of 2 agents for operational resilience - call volume at that hour only needs 1, but the second agent provides coverage if the first has a problem. The majority of the team arrive on the 7:00, 7:30, 8:00, and 8:30 schedules - peak hour, highest workforce present. Smaller groups start at 9:00, 10:00, and 11:00 (the latest). All mapped into an Excel matrix: schedule code per row, 30-minute time slots as columns, each cell showing working / break / lunch.
Automate break and lunch constraints
Two hard rules enforced automatically. Breaks: no more than 3 agents off at once per 15-minute interval, staggered across schedule codes. Lunch: two defined batches - up to 10 agents at 12:00, up to 10 more at 13:00. Simple, clean, and the coverage curve never drops below the Erlang floor because of it. The desk closes at 20:00, so the latest schedules are back before that with enough coverage for the wind-down.
Validate and present
With the matrix built and constraints enforced, I ran a final check against the Erlang minimums for every slot across every day of the week. The model surfaced any breach immediately. Once clean, it went to Operations Management as the recommended roster baseline.
Erlang Minimums by Hour
Relative call volume (% of daily peak) and minimum agents required on phones per slot. Schedules are assigned to always meet or exceed the “Min” column.
Min = Erlang C minimum agents actively on phones (excludes break/lunch). Actual analysis ran at 30-min granularity.
The Schedule Matrix
Each schedule code represents a shift starting every 30 minutes across the operational window. Sample below - the full matrix covered every slot from 07:00 to the latest possible start.
Break rule
Keeps a meaningful agent floor online at all times. Breaks are staggered across schedule codes automatically so no two clusters of agents overlap.
Lunch rule
Two defined lunch windows of up to 10 agents each. Clean, predictable mid-day coverage: first batch out at noon, second at 1PM, everyone back by 2PM.
How it works together: for every 30-minute slot, the model calculates agents currently active (total assigned to covering schedules, minus those on break or lunch at that slot). If the active count drops below the Erlang minimum, the break or lunch window for the offending schedule gets shifted until the constraint is resolved. The whole thing runs automatically on sheet recalculation.
Outcomes
SLA maintained at contractual targets for the L'Oréal account throughout and after the transition from 24/7 to 7AM-8PM.
Night-shift premium pay eliminated. Overnight agents transitioned into day window schedules through roster reallocation.
Break and lunch automation removed a chronic manual headache - roster managers stopped firefighting mid-day coverage gaps.
The model was adopted by Operations Management as the ongoing capacity planning baseline. When call volume drifted, the model immediately surfaced whether existing headcount could hold SLA.
Agent quality of life improved noticeably: predictable hours, no overnight rotation, structured break times.
Key Takeaways
The schedule granularity is everything. Working at 30-min intervals instead of whole shifts gives you a staffing curve that closely tracks demand rather than bluntly covering it.
Erlang C sets the floor - the schedule matrix is how you reach it. Neither is useful without the other.
Break and lunch automation isn't a nice-to-have. Without enforced constraints, those windows become the single biggest driver of SLA breaches.
The business case for removing overnight coverage built itself from the data - less than 7% of call volume between midnight and 7AM, full premium pay cost.
A well-structured Excel model is a communication tool as much as an analytical one. Stakeholders understand a grid far better than they understand a formula.
End of case study
Fujitsu · L'Oréal Account · Service Desk Team Manager · 2020