## A Call Center Staffing Calculator

### How many agents do I need?

This web app illustrates the difference between Erlang C, the most common methodology for calculating call center staffing, and a computer simulation. Code is available on GitHub.

Progress

### Overview

A common workforce management (WFM) question is, "how many people do I need?" Even if you know how many contacts to expect and their average duration, inbound contacts arrive randomly so how do you know how many people are required to handle the work?

Erlang C is the industry standard for solving this problem. It is computationally efficient and widely available via online calculators, Excel VBA packages, and built into most WFM software. However, Erlang C tends to overestimate the number of agents requirements. See Further Reading for a number of articles that go into more detail on Erlang C's limitations.

One alternative to Erlang C is a computer simulation. While less common due to increased complexity, computer simulations can give a much more accurate staffing plan. This interactive model illustrates the difference between Erlang C and simulation methodologies.

### Detailed Instructions

To use the calculator, fill out each form field with a whole number as follows:

• Contacts - [1 to 500] - Represents the number of inbound contacts to randomly arrive during the given time period.
• AHT - [60 to 1800] - Average handle time, AKA the average duration of each contact in seconds.
• Standard Deviation - [1 to 900] - The dispersion of handle times around the AHT. This value represents the number of seconds +/- the inputted AHT that fall within one standard deviation. This input is used by the simulation methodology to generate random contact samples.
• Service Level % - [1 to 100] - The desired percentage of contacts to be answered within the allotted threshold.
• Threshold - [1 to 300] - The other part of service level, Threshold represents the number of seconds that a contact can queue for before it is deemed "outside of service levels."
• Simulations - [1 to 500] - The number of simulations to run for each agent count along the x-axis.
• Period - [15 to 120] - The length of time, in minutes, that the given contacts will arrive in. Note that it is possible for a contact to arrive near the end of the period and its duration to run past the period length.
• Max Occupancy - [1 to 100] - The maximum percentage of an agent's time during the period that can be spent handling contacts. This is important because as contact volumes increase, there is an "economies of scale" effect where Erlang C requires less agents to hit the desired service level. This can lead to agent burnout if a maximum occupancy constraint is not set.

In the above calculator, the probability of a contact exceeding the wait time threshold is calculated using Erlang C. An excellent walkthrough of the Erlang C formula can be found here.

$$P_w = {{A^N \over N!} {N \over N-A}} \over {\left( \displaystyle \sum^{N-1}_{i=0} {A^i \over i!} \right) + {\displaystyle{A^N \over N!} {N \over N-A}}}}$$

The model above uses an event-drive simulation implemented in Javascript. This is more efficient than a time-driven simulation, as only the timestamps when a contacts arrive or depart need to be iterated through. As a result, the runtime of the simulation methodology is a function of the Contacts and Simulations inputs, and Period length has no impact.

At a high-level, each agent count (tick along the x-axis) is simulated according to the number of times set in the Simulations input. The default value of 50 simulations per agent count is typically plenty to get a decent outcome. You can re-run the simulator by resubmitting the calculate button; if the simulation results line varies wildly then you may want to increase the number of simulations.

Within each simulation, the basic algorithm is as follows. First, contact arrival events are created, and with each arrival a random handle time is assigned. Handle times are generated according to a normal distrubtion, within +/- 1 second of the AHT and Standard Deviation inputs.

The simulator keeps track of all arrival and departure events in an ordered list, which it then loops through. The timestamps of all arrivals are known at the start, but departures are inserted during iteration.

For each arrival, one of two things happens. If there are no contacts already queued and at least one available agent, the contact is immediately "connected" to an agent. In code, this is represented by decrementing the number of available agents and adding a departure event handle_time seconds into the future. Alternatively, if earlier contacts are already queued up, the contact is added to the back of the queue.

For each departure, one of two things happens. If the queue is empty, then the number of available agents is just incremented. However, if there are contacts queued, the first contact is pulled and connected to the agent, and a departure event is created just like when arrivals are immediately connected. There is an additional step here where the contact is checked against the service level threshold to see if it waited in the queue longer than acceptable.

At the end of the simulation, service level is calculated by comparing the count of contacts that exceeded the service level threshold against all contacts. These service levels are then averaged over all simulations to get the final result for each agent count.

Known limitation: The current methodology uses random numbers and the Box-Muller transform to generate handle times according to the inputted Average Handle Time (AHT) and Standard Deviations fields. See this Stack Overflow article for more detail. In most call centers, handle times tend to follow an Erlang distribution. This means that the simulator tends to under-represent left and right-tailed values and over-represent values around the AHT. While the effect on overall results is probably minimal, it is a place for future improvement.

### Technology

This website is built using HTML, CSS, and Javascript. The CSS relies heavily on Bootstrap for most styling, with only minor customizations. Javascript is used to perform Erlang C calculations, run the event-driven simulation, and display the results. Results are visualized using the Plotly javascript library. All calculations are done client side. Code for this project can be viewed on GitHub.

A lot of visual inspiration was taken from Engaging Data's awesome FIRE Calculator. Call Centre Helper also has a server-side Erlang calculator that served as an example, and their Erlang C Formula walkthrough was helpful in wading through the math.