What is the best way to load test a contact center?
The best way to load test, or more accurately, performance test, a contact center is to place synthetic calls through the same carriers, IVR, AI agents and routing your customers use, at your measured peak plus the headroom you want proof for, with synthetic agent sessions answering on the other side. Measure arrival rate as well as concurrency, hold the load long enough to find slow failures, and check the outcome of every call, not just whether it connected.
The calls are real and the callers are synthetic, so nobody phones in with a real problem, and no live agent is tied up because synthetic agent sessions take the calls. The part most programs skip is checking outcomes. A test that proves the trunk carried the calls has measured capacity and little else. A test that proves each call reached the right outcome, with usable audio, at an agent who received the caller’s details, has measured what customers experience.
A contact center load test covers four things at once: whether the platform carries the volume, whether each interaction still reaches the right outcome under that volume, whether the audio holds up, and whether the agent side works when the calls land. Each fails independently. For the IVR specifics, see our post on load testing IVR systems for peak traffic. This page goes wider, to the agent side and to the whole center under load.
What tests make up a contact center performance test?
There are five tests that fall into the performance testing category, and running one of them is not the same as having tested the center. “Load testing” carries a built-in idea of slamming the platform until it breaks, which is why performance testing is the more accurate name for the program. Each of the five finds a different class of failure, and each one belongs in an annual regimen.
Maximum call arrival rate. A ramp that starts gradually and is tilted steeper on each run, to find the highest arrival rate the platform sustains up to the limit of your trunking.
Maximum call volume. You are contracted for a number of concurrent calls, and the test is what happens to the call that arrives above it, and to the twenty or thirty behind that one. Is there overflow support, how much will it absorb, and what happens once the overflow is exceeded? The internal components have to carry the increase too. This is the stress test, and the ceiling is what you are looking for.
Endurance. Hours at close to maximum volume, because memory leaks come from poorly designed software and from call volumes whose processing never lets memory be recovered, and neither one shows up in a short run. This is the soak test.
Component targeting. Reading data from a database costs compute. Writing costs compute and disk access interleaved with the read requests. Writes can be buffered, the buffers fill, and the errors start when they do. Knowing where each component gives way is worth more than knowing the platform held.
Disaster recovery. A trunk group goes out of service, an SBC fails, a CCaaS resource goes down. There are many disaster possibilities and these are the ones most often left untested, which is how an operation stops for a day over a component whose fallback nobody had ever exercised.
How do you work out the peak you should test against?
Start with what you’re contracted to, then test what happens beyond it. Four questions settle the target, and they’re the ones to put to your platform provider in writing: what is the contracted maximum concurrency, what happens when it’s exceeded, what is the maximum call arrival rate, and what happens when that’s exceeded. The second and fourth answers are the ones nobody has tested, and a number you’re entitled to isn’t always a number that holds.
If you have traffic data, the arithmetic is short. Take a center that records 1,200 calls in its busiest 15 minutes, with an average interaction of 4 minutes. The average arrival rate is 1,200 calls over 900 seconds, about 1.33 calls per second. The average concurrency is that rate multiplied by the 240-second interaction, about 320 calls in progress. These figures are illustrative averages, so treat them as a starting point. Real traffic spikes inside the quarter hour, interactions vary in length, and transfers and queue time add concurrency the arithmetic doesn’t see.
If you don’t have a measured peak, the test is how you find one. Finding the maximum concurrency and the maximum call attempt rate is a legitimate goal of the exercise, not a prerequisite for it.
Then clear the run before you build it. A load test against a production platform usually needs the provider’s approval, with longer lead times than people expect. Amazon Connect requires approval at least two weeks before the test date and limits testing to 6 PM to 6 AM in the Region’s local time zone (AWS load testing policy). Genesys Cloud requires prior authorization for all automated testing, also at least two weeks ahead, within an 11 PM to 5 AM window (Genesys automated testing FAQ). Check your own platform’s policy, agree to the window, name the person who can stop the test, and tell your carrier what’s coming.
How should the load ramp, and how long should it run?
Two ramps, and they run in that order. The first is a spike test, zero to the maximum call arrival rate, with the steepness of the ramp varied on each run until you find the rate at which the equipment stops keeping up. The second is a volume ladder, built once the maximum arrival rate is known, laddering volume so the cumulative arrival rate reaches its maximum as total call volume reaches its own. The second ramp is where internal components give way, and database retrievals and updates, routing decisions and call queuing all move under the combination in a way neither volume nor arrival rate produces on its own. Watch the call arrival rate separately from concurrency. Calls per second at the trunk is often the limit that bites first, and a center sized comfortably for concurrent calls can still fail on how fast they arrive.
One design decision decides whether the test tells you anything. If the generator waits for one interaction to finish before starting the next, the offered load falls as the platform slows, and the test reports a system coping with volume it never received. New calls have to keep arriving at the planned rate however long the calls in progress are taking.
For a soak, I work to six to twelve hours with no errors showing, at about 80% of the maximum call attempt rate and concurrency. That’s a working rule, not an industry requirement. Match the duration to the length of your own peak period, because a soak exists to find the slow leak that only appears after the third hour.
What do you measure besides whether the calls connected?
Measure the outcome of each interaction, and measure the audio rather than listening to it. Under load, the common failure isn’t a refused call. It’s a call that connects, sounds fine to a human spot check, and reaches the wrong place or arrives without the caller’s details.
Measure voice quality on every call the test places. Set a floor before the test and assert against it, so audio is judged against a number rather than by ear. Two methods sit behind that number, and they aren’t the same measurement. Where reference audio exists, the test measures the percentage alignment between the reference waveform and the received waveform, and a configuration maps that percentage to a MOS score. On the real-agent side, where there’s no reference, voice quality is estimated from packet loss, jitter and round-trip time using the E-model in ITU-T G.107 (ITU-T G.107). Neither is a listening test.
How do you load test the agent side?
Put synthetic agent sessions on the receiving end, so calls land somewhere that behaves like an agent population. Synthetic agent sessions exercise platform login, routing, interaction handling and the media path without a physical workstation for every session, so the test can scale beyond the number of desktops you can stand up.
That’s the part a desktop-based approach can’t reach. Nobody stands up a workstation for every agent to prove a routing change holds across the whole floor, so the change ships proven on a handful of desktops and meets the full agent population on go-live morning.
The agent side catches a different class of failure from the customer side. Logins that work one at a time can queue when they all arrive at once. Routing that holds at low volume can mis-assign skills at peak. And the screen pop has to fire with the call-related data before the agent would pick up.
Decide four things before an agent-side run: how many sessions to stand up for a given customer-side volume, whether they log in before the calls start or during the ramp, which skills and queues they’re assigned to, and what each session asserts when a call arrives.
On scale, the number to quote is the customer’s requirement rather than a ceiling. We have run 10,000 concurrently. That was our customer’s working number, not our limit. We scale to the number you need.
Where do load failures actually appear?
They rarely appear where the capacity plan is looking. The components usually hold. What moves is timing, and timing sends calls down paths nobody exercised at low volume.
Instrument three places before the peak rather than after it. The first is a dependency that slows down instead of refusing, so a timeout branch written years ago starts carrying real traffic. The second is the join between two components, where each reports success and the thing handed between them doesn’t arrive. The third is the agent side, where the interaction is fine and its arrival isn’t.
One more is worth asking about, because aggregate capacity hides it. If your traffic is spread across more than one carrier path, can the busiest one carry the required load on its own, and what happens to the rest when traffic shifts off one of them? A test that only generates load inside the platform never asks.
What evidence should a load test produce?
Produce a result for every assertion and the record behind each one. At volume that’s harder than it sounds: a 2% failure rate across fifty thousand calls is a thousand failures nobody can diagnose from a summary. For each call, the record should hold the SIP signaling, the audio, the transcript, the CTI payload that reached the agent desktop and a pass or fail for every assertion, all timestamped. Timestamps do the attribution, because a payload that arrived late and one that never arrived look identical in a summary and are different defects.
Decide what a pass looks like before the run, dimension by dimension, because one overall number hides what you most need to know. A 99% pass rate is reassuring until the failures turn out to sit on the payment route or the emergency line. Agree each tolerance with whoever owns the service.
The second test is a ladder of sheer volume. Once the max call arrival rate is determined, ladder in the volume with the cumulative arrival rate reaching the max number when the overall call volume is also reaching a max volume. Often, internal components and services will start to fail. DB retrievals and updates, routing decisions and call queuing are frequently impacted by the changes in volume and call arrival rates.
| Dimension | What a pass looks like |
|---|---|
| Capacity | The target load was reached and held for the planned duration |
| Outcome | Interactions reached the outcomes the test asserted |
| Routing | Calls arrived at the expected queue with the expected skill |
| Agent side | The interaction arrived, and the call-related data arrived with it |
| Audio | Voice quality stayed above the agreed floor, on the stated measurement |
| Stability | No deterioration across the soak beyond what was agreed in advance |
How do you size a load test without buying capacity you don’t need?
Size it to the peak you have to prove. Everyday testing and regression aren’t rationed by port count, while load testing is sized to the peak that needs proving. The two halves of a testing program have different shapes. The everyday half runs all year and follows the size of the center. The load half runs before a peak, a launch or a cutover, and follows the number you’re trying to demonstrate. Before you compare quotes, ask what each one has been sized to.
Frequently Asked Questions
-
A load test proves the platform holds the peak you expect. A stress test finds where it stops holding, and finding that ceiling is the goal rather than a by-product. Run both, and use the stress test to find your peak when you don’t have the figure.
-
Start at the concurrency you are contracted for, then go past it. A contracted number is what you are entitled to rather than something anyone has proved, so the test that matters is what happens to the call that arrives above the limit and to the twenty or thirty behind it. Test the overflow path as well, how much it absorbs and what it does once it is full. If you have no contracted figure and no measured peak, finding the ceiling is a legitimate goal of the run.
-
At least once a year across all five tests, and again before any peak, launch or cutover you need proof for. The annual run catches what shifted underneath you between peaks, and platform updates, integration changes and traffic growth nobody sized for all qualify. A result from eighteen months ago describes a center you no longer run.
-
Yes. Synthetic agent sessions exercise platform login, routing, interaction handling and the media path without a physical workstation for every session, so the test scales beyond the number of desktops you can stand up.
-
Usually yes, and often production is the only environment where the result means anything, because a scaled-down environment proves something about the environment rather than about your center. It does need planning. The callers are synthetic but the calls are real, so a test at volume shares trunks, platform capacity and downstream systems with everything else running. Agree the window, name the contact who can stop it, tell your carrier, and get the platform’s approval where the platform requires it.
-
MOS runs from 1 to 5, and what matters for a contact center is the floor you set before the test rather than a universal score. Agree it with whoever owns the service, assert against it on every call the test places, and record which measurement produced it, because a score estimated from packet loss, jitter and delay and a score derived against reference audio are not the same measurement.
