Back to Experience
Case StudyFujitsu · L'Oréal Account · 20206 min read

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.

Erlang CWorkforce PlanningExcel AutomationSchedule OptimisationService Desk

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.

A = λ × AHT// traffic intensity in Erlangs
SL = 1 - C(N,A) × e^(-(N-A)×t / AHT)
where t = target answer time, C(N,A) = Erlang C queuing probability

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.

01

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.

02

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.

03

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.

04

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.

05

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.

06

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.

SlotCall volumeMin agents
07:00
8
08:00
13
09:00
15
10:00
17
11:00
16
12:00
14
13:00
13
14:00
15
15:00
15
16:00
16
17:00
14
18:00
12
19:00
8

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.

CodeWindowBreakLunchNotes
A106:00 - 14:3008:0010:30Opening resilience (2 agents)
B107:00 - 15:3009:0012:00Peak start wave
B207:30 - 16:0009:3012:00Peak start wave
B308:00 - 16:3010:0012:00Peak start wave
B408:30 - 17:0010:3013:00Peak start wave
B509:00 - 17:3011:0013:00
B610:00 - 18:3012:0013:00
B711:00 - 19:3013:0015:00Latest start
... continues every 30 min through the end of the operational window
Max 3agents on break per 15-min interval

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.

10 + 10max per batch — 12:00 and 13:00 slots

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

01

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.

02

Erlang C sets the floor - the schedule matrix is how you reach it. Neither is useful without the other.

03

Break and lunch automation isn't a nice-to-have. Without enforced constraints, those windows become the single biggest driver of SLA breaches.

04

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.

05

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

Back to Experience