Power Your Software Testing with AI Agents and Cloud
The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.
- TestMu AI (Formerly LambdaTest)
- /
- Blog
- /
- Contact Center Load Testing: How to Size and Run a Test
Contact Center Load Testing: How to Size and Run a Test
Contact center load testing for voice, chat, and agent desktops: size concurrent calls with Erlang B and C, check platform quotas, and read results by layer.
Published on:
Contact centers usually fail at peak on a limit nobody measured: a platform quota on simultaneous calls, a trunk with too few channels, or a CRM API that throttles the screen pop an agent is waiting for.
Amazon Connect, for example, sets a default of 10 concurrent active calls per instance, and once that quota is exceeded, new contacts get a reorder tone, also known as a fast busy, according to its service quotas documentation.
Contact center load testing finds those limits before your customers do, and the size of the test should come from your own traffic rather than a round number. The sizing script in this guide turns one peak interval of call and chat data into concurrency targets; I ran it on Node.js 24, and the output shown is the real run.
Overview
Contact center load testing holds a realistic number of simultaneous calls, chats, and agent sessions against your telephony, IVR, contact center platform, and CRM to find the first limit that breaks. Size it from your busiest interval: Little's law gives concurrent contacts, Erlang B gives the phone lines you need, and Erlang C gives the agents.
What Should a Contact Center Load Test Cover?
- Concurrent call quotas: Contact center platforms cap simultaneous calls per instance, and callers past the cap hear a fast busy tone. Check the quota applied to your own account before a contact center load test, because raising it can take weeks.
- Erlang B: Erlang B estimates how many phone lines or SIP channels you need so that only a target share of calls is blocked at a given load. The highest hold level in your test should reach that line count.
- Erlang C: Erlang C estimates the probability that a caller has to wait for an agent, which turns your staffing and service level targets into the agent count the test environment needs.
- Chat concurrency: Chat load is measured in open conversations, and idle chats can still count against a platform's chat quota. Model how many chats each agent handles at the same time.
- Caller-side metrics: Connection rate, dropped calls, and response latency at the 95th and 99th percentiles show what callers experienced, while platform and server metrics show why. A useful contact center load test records both on one timeline.
Can You Run One Without Building a Call Lab?
Yes, for the voice layer of a contact center load test. TestMu AI Agent Testing places real calls to a phone agent, holds a target number of concurrent calls, and reports the breaking point and safe operating capacity, so you do not need a dialer of your own.
What Is Contact Center Load Testing?
Contact center load testing simulates the number of simultaneous callers, chat users, and agents you expect at peak, then measures where the contact center stops answering, slows down, or drops contacts. It covers the whole path a customer touches: the phone line or chat widget, the IVR or virtual agent, queues and routing in the contact center platform, and the agent desktop and CRM behind it.
It is also called call center load testing or contact center performance testing. Functional testing confirms that one call is routed correctly; load testing confirms that the hundredth simultaneous call still is.
The test patterns are the ones any system uses, applied to contacts instead of web requests, and the load testing guide covers the general method:
- Load test - holds the concurrency of your busiest real interval to confirm the contact center carries today's peak.
- Stress test - keeps adding calls past your line count or platform quota until something fails, so you learn which limit breaks first and what callers hear when it does.
- Soak test - holds normal peak for several hours to surface slow leaks, such as telephony ports that are not released or recording storage that fills up.
- Spike test - jumps from quiet to peak in seconds, the shape of a billing error or a service outage that sends every customer to the phone at once.
If only the phone menu is in scope, the guide to IVR performance testing covers prompt latency, speech recognition, and port capacity in depth. A contact center test adds everything around the IVR.
Which Parts of a Contact Center Break First Under Load?
Each layer runs out of a different resource, and callers notice each failure differently. The layer that breaks first is usually a configured limit, such as a quota or a channel count.
| Layer | What runs out | What callers or agents see | Where the limit is set |
|---|---|---|---|
| Phone lines and SIP trunks | Channels, and new calls per second | Busy or fast busy tone, failed call setup | Carrier contract and trunk configuration |
| Contact center platform | Concurrent call, chat, and queue quotas | Reorder tone, chats that fail to start | Platform service quotas per instance |
| IVR and voice bots | Ports, speech recognition and synthesis sessions | Long silences, prompts that time out | IVR licences and speech provider limits |
| Queues and routing | Agents, queue capacity | Long waits, abandoned calls, overflow | Staffing and routing rules |
| Agent desktop and CRM | API rate limits for screen pops and lookups | Agents wait for the customer record, handle time grows | CRM and platform API throttling |
| Outbound dialer | Calls per second | Campaign falls behind, calls queue before dialing | Telephony provider rate limits |
Amazon Connect's quota page shows how low the platform ceilings can start: 10 concurrent active calls and 500 concurrent active chats per instance, at most 10 contacts queued at once in a single agent queue, and quota increases that can take up to 3 weeks to approve and deploy. The same page notes that its defaults apply to new accounts, so the quota applied to an older account can be lower; read the applied value before you plan the test.
Agent desktops hit API limits instead. Amazon Connect throttles its API per account and Region rather than per user, with most operations defaulting to 2 requests per second and a burst of 5, so a custom desktop that calls the API for every agent can be throttled before the phone lines are full.
Twilio grants each account one call per second on its /Calls API by default; accounts with an approved Business Profile can raise it to 5 in the Console, and calls beyond the limit are queued, per the Twilio Call resource documentation.
That makes the call setup rate a ceiling of its own for test generators: at one call per second, a dialer built on that API needs more than a minute and a half just to start 94 calls. Measure how long your ramp takes before you blame the system under test.
How Many Concurrent Calls Should a Load Test Hold?
Hold the concurrency your busiest interval actually produced, then the line count where calls start to be blocked, then a step above it. Little's law gives the first number and Erlang B gives the second.
Little's law states that the average number of items in a queuing system equals their average arrival rate multiplied by the average time each spends in the system, L = λW, as John Little restates in Little's Law as Viewed on Its 50th Anniversary (Operations Research, 2011).
For a contact center, λ is calls per second in the peak interval, and W is everything a call holds a line for: IVR time, queue wait, and talk time. After-call work keeps the agent busy but frees the line, so it counts toward agents and not toward lines.
Teletraffic engineering uses the same input under another name. Offered traffic A, in erlangs, is the call arrival rate multiplied by the mean holding time; Erlang's B-formula gives the probability that a call is blocked on n lines carrying that traffic, and Erlang's C-formula gives the probability that a caller has to wait, as defined in Villy B. Iversen's Teletraffic Engineering and Network Planning (Technical University of Denmark, 2015).
The script below takes one peak interval and returns the numbers a test plan needs. Replace the inputs with the figures from your ACD or platform reports for the busiest 30 minutes you have on record.
// Size a contact center load test from one peak interval of your own traffic.
// Inputs: calls and chats per hour in the busiest interval, plus average times in seconds.
const peak = {
callsPerHour: 900, // busiest 30-minute interval x 2
ivrSeconds: 60, // time in the IVR before queueing
talkSeconds: 300, // talk + hold time with an agent
wrapSeconds: 60, // after-call work (agent busy, line free)
chatsPerHour: 600,
chatSeconds: 600, // average chat duration
chatsPerAgent: 3, // concurrent chats one agent handles
};
const target = { answerWithinSeconds: 20, serviceLevel: 0.8, blocking: 0.01 };
// Erlang B by recursion: E(0) = 1, E(x) = A*E(x-1) / (x + A*E(x-1))
function erlangB(A, n) {
let e = 1;
for (let x = 1; x <= n; x++) e = (A * e) / (x + A * e);
return e;
}
// Erlang C from Erlang B: probability that a caller waits at all
function erlangC(A, n) {
if (n <= A) return 1;
const b = erlangB(A, n);
return (n * b) / (n - A * (1 - b));
}
// Agents: smallest n that answers the target share within the target time
const lambda = peak.callsPerHour / 3600; // calls per second
const handle = peak.talkSeconds + peak.wrapSeconds; // agent time per call
const agentErlangs = lambda * handle;
let agents = Math.ceil(agentErlangs) + 1, wait, asa, sl;
for (;; agents++) {
wait = erlangC(agentErlangs, agents);
asa = (wait * handle) / (agents - agentErlangs);
sl = 1 - wait * Math.exp(-(agents - agentErlangs) * target.answerWithinSeconds / handle);
if (sl >= target.serviceLevel) break;
}
// Lines: a call holds a line through IVR, queue wait and talk (not wrap-up)
const lineSeconds = peak.ivrSeconds + asa + peak.talkSeconds;
const concurrentCalls = lambda * lineSeconds; // Little's law: L = lambda * W
let lines = Math.ceil(concurrentCalls);
while (erlangB(concurrentCalls, lines) > target.blocking) lines++;
// Chat: concurrency and the agents it needs at a fixed chats-per-agent cap
const concurrentChats = (peak.chatsPerHour / 3600) * peak.chatSeconds;
const chatAgents = Math.ceil(concurrentChats / peak.chatsPerAgent);
const r = (v, d = 1) => Number(v.toFixed(d));
console.table({
"Agent workload (erlangs)": r(agentErlangs),
"Agents for 80/20 service level": agents,
"Probability a caller waits": r(wait, 3),
"Average speed of answer (s)": r(asa),
"Concurrent calls on lines (L)": r(concurrentCalls),
"Lines for 1% blocking (Erlang B)": lines,
"Concurrent chats": r(concurrentChats),
"Chat agents at 3 chats each": chatAgents,
});
console.log(`Load test targets: hold ${Math.ceil(concurrentCalls)} calls, then ${lines} (the blocking edge), then ${Math.ceil(lines * 1.5)}.`);This is the output from my run, unedited:
$ node size-load-test.mjs
┌──────────────────────────────────┬────────┐
│ (index) │ Values │
├──────────────────────────────────┼────────┤
│ Agent workload (erlangs) │ 90 │
│ Agents for 80/20 service level │ 98 │
│ Probability a caller waits │ 0.307 │
│ Average speed of answer (s) │ 13.8 │
│ Concurrent calls on lines (L) │ 93.5 │
│ Lines for 1% blocking (Erlang B) │ 110 │
│ Concurrent chats │ 100 │
│ Chat agents at 3 chats each │ 34 │
└──────────────────────────────────┴────────┘
Load test targets: hold 94 calls, then 110 (the blocking edge), then 165.Each number maps to a step in the test plan:
| Script output | Value | What the load test does with it |
|---|---|---|
| Concurrent calls on lines | 93.5 | First hold level, the peak you already see in production |
| Lines at one-in-a-hundred blocking | 110 | Second hold level, the point where callers should start hearing busy signals |
| Line count x 1.5 | 165 | Stress level, to see which limit fails first past the design point |
| Agents for an 80/20 service level | 98 | Agents, or simulated agents, the queues need during the test; with fewer, queue wait masks every other result |
| Concurrent chats | 100 | Chat sessions to hold alongside the voice test, served by 34 agents at three chats each |
The two formulas make different assumptions. Erlang C assumes callers wait in an unlimited queue, while Erlang B assumes a caller who finds every line busy is lost, and a real contact center sits between the two, which is why the plan holds load at both numbers.
How Do You Load Test Chat and Messaging Channels?
Measure chat load as the number of open conversations. A chat stays open while the customer types, while a bot or agent answers, and while it waits in queue, so concurrency builds the way it does for calls: chats per second multiplied by chat duration.
On Amazon Connect, the chat quota defaults to 500 concurrent active chats per instance and includes SMS, WhatsApp, and Apple Messages for Business. Waiting chats count against it, and so does a chat whose customer has gone silent for hours; past the quota, the API call that starts a chat fails with a quota exceeded error, according to the same quota page.
Starting chats is rate limited as well: the StartChatContact operation defaults to 5 requests per second with a burst of 8 on Amazon Connect. A generator that opens every chat in the first second hits that throttle before it reaches capacity, so ramp chats in over minutes.
- API-level sessions - open and hold conversations against the chat API from a script-based load tool to test platform quotas and the bot's reply time at volume.
- Real channel clients - drive the web chat widget in real browsers for a smaller number of sessions to catch reconnect and rendering problems the API path skips.
- Agent concurrency - set how many chats each real or simulated agent accepts at once, because that setting decides how fast the chat queue grows.
- Idle sessions - keep a share of conversations silent for the whole hold period, since idle chats use quota without generating traffic.
How Do You Run a Contact Center Load Test?
Run it in eight steps, whichever tool places the calls. The roundup of contact center testing tools compares the tools that can generate calls at volume.
- Pick the interval - export calls offered, chats offered, average handle time, and IVR time for the busiest 30 minutes of the last quarter from your ACD or platform reports.
- Size the targets - run the sizing script on those figures to get concurrent calls, the blocking-edge line count, and the agent count.
- Check every ceiling - list the platform quota, trunk channels, calls per second, speech recognition sessions, and CRM API limits, and raise any that sit below the targets weeks ahead of the test.
- Agree on the test window - tell your carrier and platform provider when test calls will run and from which numbers, and route test traffic to dedicated test numbers and queues so it never reaches real customers.
- Build a traffic mix - spread calls across the menu paths, languages, and intents your reports show, including transfers, abandons, and callers who press nothing.
- Ramp, hold, drain - ramp to the first target, hold until queue wait settles, step up to the next target, then stop new calls and let active ones finish.
- Measure each layer - record caller-side results from the test tool and platform-side metrics, such as quota usage, queue size, and API throttling, on the same timeline.
- Compare with the model - if blocking or long waits appear well before the predicted line or agent counts, the bottleneck is a limit you did not list in step three.
Which Metrics Show a Contact Center Failing Under Load?
Read load achieved first; every other metric is only meaningful if the test actually held its target. Then read each metric per concurrency level rather than as one average for the run.
| Metric | What it tells you | Read it alongside |
|---|---|---|
| Load achieved | Whether the generator held the target number of calls or chats | Ramp duration, generator errors |
| Connection rate | The share of calls that connected | Busy and reorder tones, SIP error codes |
| Post-dial delay | Time from dialing to ringing | Trunk and carrier capacity |
| Response latency at P95 and P99 | How long the slowest callers wait for each IVR or bot reply | Speech and language model provider limits |
| Average speed of answer | Queue wait before a human answers | Agent count versus the Erlang C prediction |
| Abandon and drop rates | Callers who hung up in queue, and calls that ended unexpectedly | Queue wait, media server health |
| Chat first response time | Wait for the first reply in a new chat | Chat quota usage, agent chat capacity |
| Screen-pop latency | Time for the agent desktop to show the customer record | CRM and platform API throttling |
Audio quality under load, such as MOS, jitter, and packet loss, needs its own measurements, covered in the guide to voice quality testing. For AI voice agents, the guide to voice agent latency testing explains where a response latency measurement should start and stop.
How Does TestMu AI Load Test Phone Agents?
TestMu AI Agent Testing runs performance tests against phone agents as a test type separate from its conversation checks. A test places real calls over live telephony to your agent, holds the target number of concurrent calls for a hold duration you set between 1 and 120 minutes, and replaces each call that ends so the load stays at target.
Scoring uses only the steady hold window, so ramp-up and wind-down do not distort the numbers. Results include load achieved, connection reliability, agent response latency at P50, P90, P95, and P99, results by concurrency level, and automated findings for the breaking point and the safe operating capacity.
It measures what the caller experiences and does not observe server resources or model provider limits inside your stack, so pair it with your platform's own metrics from step seven. The feature is enabled per organization, and a test never goes above the number of concurrent calls your organization can run.
Note: Hold real concurrent calls against your phone agent and find its safe operating capacity with TestMu AI Agent Testing. Try TestMu AI free
What Makes a Contact Center Load Test Misleading?
Most misleading results come from the test setup rather than the contact center, and to a carrier, a burst of load-test calls looks like any other outbound campaign. Check these before you trust a pass:
- Spam labeling - launching a high-volume voice campaign can look like spam to carriers, which work with third-party analytics vendors to label calls, and SHAKEN/STIR attestation is only part of that decision, per Twilio's guide to high-volume voice.
- A ramp throttled by the generator - if the dialer's calls-per-second limit queues call starts, the hold window begins below target; confirm load achieved before reading anything else.
- One happy path - a test where every caller presses 1 exercises one queue and one IVR branch, while a real peak mixes menu choices, transfers, and abandons.
- Wrap-up left out - agents in after-call work are unavailable even though their line is free, so size agents with handle time that includes wrap-up, as the script does.
- Different quotas in staging - a staging instance often keeps default quotas while production has raised ones, so a test can pass in staging and block in production, or the other way round.
- Averages instead of percentiles - average response latency can look stable while the slowest callers wait several seconds, so read P95 and P99 at each concurrency level.
Conclusion
Start with one export: the calls, chats, and handle times from your busiest 30-minute interval last quarter. Run the sizing script on it, compare the line count with your platform quota and trunk channels, and raise anything below target before you book the test window.
For the voice layer, set up a phone suite with the inbound phone agent testing guide, then run the three hold levels as performance tests from TestMu AI contact center testing.
Author
Chaitanya Sharma is an AI Product Manager at TestMu AI, where he builds agentic AI capabilities focused on computer vision and multi-modality, moving testing beyond static script execution toward autonomous, agent-driven workflows. Before TestMu AI he shipped 135+ features at Sprinklr for a no-code community and website builder used by Fortune 500 enterprises including Dell, Samsung, and Polestar. At Policybazaar he led the zero-to-one launch of a digital lending and insurance marketplace embedded in Bahrain's dominant payments app, building a risk-intelligence engine that compressed loan-approval times by 80%. He explored machine learning and NLP through research at the University of Cambridge, and holds a B.Tech from Delhi Technological University.
Reviewer
Samyak Goyal is a Senior Member of Technical Staff at TestMu AI engineering Kane CLI, the command-line tool that runs browser automation from the terminal, where a flow described in natural language executes in a real Chrome browser and returns pass or fail with shareable proof. He is a backend engineer with 4+ years of experience, previously an SDE at Innovaccer, where he built APIs, introduced Kafka, and cut deployment from weeks to hours. Samyak also builds multi-agent systems, skill-orchestration frameworks, and a personal copilot that indexes 200+ microservice repositories.
Contact Center Load Testing FAQs
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance
- Advanced access controls
- Advanced data retention rules
- Advanced Local Testing
- Premium Support options
- Early access to beta features
- Private Slack Channel
- Unlimited Manual Accessibility DevTools Tests






