Contents
- 01 The Voice Agent, End-to-End
- 02 How We Benchmarked
- 03 The Media Plane Holds: SFU at 1,000 Rooms
- 04 SIP Inbound: The Worker Is the Limit
- 05 The Single Biggest Latency Lever
- 06 Picking the Right Speech Vendors
- 07 Inside the Hot Path
- 08 Naturalness: Barge-In and Recovery
- 09 Capacity Plan: 1,000 Concurrent Calls
- 10 What We Ship Next
- 11 The SimplAI Commitment
Why this report exists.
A voice agent feels effortless when it works. You speak, it listens, it answers — naturally, without awkward pauses, and without falling over when the next thousand callers join the line. The hard part isn’t the demo. It’s holding that quality on the thousandth concurrent call.
At SimplAI, we run voice agents in two flavors that share the same underlying stack: outbound and inbound calling agents that talk to customers over real phone lines, and embedded conversational agents that talk to users in a browser or app over WebRTC. Both demand the same thing — low latency, human-like turn-taking, and steady behavior under load.
Over the past quarter we ran a structured benchmark program against our voice stack: SFU concurrency, SIP inbound capacity, end-to-end Voice Agent Response Time (VART), STT and TTS vendor characterization, agent-pipeline TTFT under load, and barge-in latency. This post is a distilled, no-spin tour of what we measured, where the bottlenecks actually live, and how we’re paving the road from here to reliable 1,000-concurrent enterprise deployments.
The Voice Agent, End-to-End
Whether the caller arrives over a phone line or a browser, the path looks the same once the call is on the wire. Audio enters the LiveKit SFU and a voice-agent worker is dispatched into the room. The worker handles the audio plane (VAD, STT, TTS, turn-taking, barge-in) and forwards each conversational turn to the Agent-Service Orchestration layer, which runs agentic orchestration — conversation state, tools, function calls — and makes its LLM calls through the LLM Router. The agent’s reply streams back through the SFU to the caller.
Every block is an independently scalable Kubernetes deployment — so we can right-size each layer against its actual binding constraint rather than the largest one.
The voice-agent service is co-located with the SFU in each region. Section 05 shows why this is the single largest user-perceived latency lever in the entire system.
How We Benchmarked
All numbers in this post come from controlled, repeatable load tests against live SimplAI infrastructure — not vendor marketing material. We deliberately mixed test methodologies so each layer was measured both in isolation and as part of the end-to-end path.
| Regions | Load Generators | Measurement |
|---|---|---|
|
Central-US
Primary deployment
|
Synthetic 1:1 audio
SIPp UAC
Scripted barge-in client
|
Protocol timestamps
(T0–T5)
RMS-energy first-byte detect
|
|
Mumbai (APAC)
Cross-region tests
|
OpenAI-compatible
streaming /chat/completions
at 5 → 1,000 concurrency
|
VART, TTFT, barge-in
distributions captured
per-run, p50/p95/p99
|
Methodology in detail
SFU concurrency was driven with a synthetic 1:1 audio load generator ramping from 100 → 1,000 rooms in 5 rooms/sec increments, holding each step for 3–5 minutes. SIP inbound was driven with SIPp as a UAC, issuing standard INVITE → 200 OK → ACK → BYE flows at 5 calls/second. Call-setup latency and Voice Agent Response Time were captured from a single client that timestamps each protocol event (T0–T5) and detects the first audio byte via an RMS-energy threshold on the agent’s track. Agent-pipeline TTFT was measured by sending OpenAI-compatible streaming /chat/completions requests directly at each layer (LLM Router, agent-service end-to-end) at 5 → 1,000 concurrency. Barge-in was measured with a scripted client that injects a 2-second interrupt utterance 2.0 s into the agent’s welcome and times the silence-and-recovery sequence. STT and TTS layers were characterized using a combination of vendor-published benchmarks and field measurements from our deployment.
The Media Plane Holds: SFU at 1,000 Rooms
The first question for any voice platform is whether the media plane survives. We pushed the LiveKit SFU from 100 to 1,000 concurrent 1:1 audio rooms, with HPA configured at 80% CPU target and replicas bounded between 2 and 10.
| Concurrent Rooms | Pods | Success | Packet Loss | Hottest Pod CPU |
|---|---|---|---|---|
| 100 | 2 | 100% | 0.000% | 625 m |
| 1,000 | 3 | 100% | 0.000% | 2,252 m of 4,000 m |
HPA crossed from 2 to 3 pods around the 200-room threshold, then held at 3 pods all the way to 1,000 rooms. The hottest pod was at 56% of its CPU limit and 43% of memory at peak — meaningful headroom, no queuing in room creation, no observed packet loss.
For 1:1 voice traffic, the SFU is not the bottleneck at the scales our customers need. Per-room CPU cost trends downward at higher concurrency (~10 m → ~7 m per room) as shared signaling and connection overhead amortizes. We have room to grow before we touch this layer.
SIP Inbound: The Worker Is the Limit
For our calling-agent customers, SIP capacity matters more than SFU capacity. We drove inbound calls at 5 calls/sec and varied voice-agent worker resources to find the binding constraint. Every failed call we observed traced back to the agent worker — never the SIP server, never the SFU. LiveKit’s load-based scheduling rejects new INVITEs when all workers are above its load > 0.7 threshold and the SIP server returns a protocol-correct 486 Busy Here.
| Worker Pod CPU | Observed Capacity | Notes |
|---|---|---|
| 1 core | ~3 calls / pod | Needs ≥ 2–3 GB RAM; OOMs at 1 GB |
| 2 cores | ~7 calls / pod | Stable up to 10 calls / 2 replicas |
| 4 cores | ~12 calls / pod | Linear with CPU; memory not constraining |
SIP capacity scales linearly with worker CPU. To grow inbound, we grow agent workers — and the Section 09 capacity plan does exactly that.
The takeaway is simple: SIP capacity scales linearly with worker CPU. The SIP server, room admission, and SFU all stayed silent during stress.
The Single Biggest Latency Lever: Same-Region
VART — Voice Agent Response Time, from user end-of-speech to first byte of agent audio — is the metric users actually feel. We measured it in two topologies: voice-agent service and SFU in the same region, vs. across regions. All VART numbers in this post come from real-world scenarios we benchmark against — not curated demo runs. They are designed to mirror the conditions our enterprise customers actually run in, including realistic concurrency, prompt complexity, and network paths.
| Metric | Cross-region | Same-region | Improvement |
|---|---|---|---|
| Welcome latency (room → first byte) | 3.76 s | 0.56 s | −85% |
| VART (end-of-speech → first reply byte) | 3.70 s | 1.80 s | −51% |
| Agent join time | 1.126 s | 0.002 s | −99.8% |
“Regional topology — not per-service resourcing — is the largest single user-perceived latency lever in the entire stack.”
Several stages in the welcome and VART paths involve round-trips between the agent worker and the SFU. Each round-trip compounds inter-region RTT; co-locating the worker collapses the dispatch overhead from over a second to ~2 ms. Connection time remains ~3.0 s either way — that one is bounded by client-to-SFU transport, not by where we deploy the worker.
The < 2-second VART target, budgeted
We size each layer against a less than 2-second VART target, measured under real-world traffic — not demo conditions. Here’s how the budget breaks down across stages, anchored on the vendor benchmarks in Section 06 and the layer measurements in Section 07.
Picking the Right Speech Vendors
STT and TTS are the two layers we don’t build ourselves. We bias toward vendors that win on the combination of latency, accuracy, and conversational features (turn-taking, diarization), then we measure them in our own pipeline rather than trusting the marketing page.
STT — Deepgram Nova-3 / Flux
For speech-to-text, what matters for VART is finalize latency: the delay between the user finishing their sentence and the complete transcript reaching the LLM. Streaming partials don’t help if the finalize stalls. Deepgram Flux is purpose-built for voice agents, with native end-of-turn detection that makes turn-taking feel natural.
| Metric | Deepgram Nova-3 | Deepgram Flux [In Use] |
|---|---|---|
| Streaming latency (P50) | ~300 ms | sub-300 ms |
| WER (English, vendor) | 5.3% batch / 6.8% streaming | Nova-3 quality level |
| Speaker diarization | Yes | Yes |
| Native end-of-turn detection | — | Yes |
TTS — ElevenLabs Flash v2.5
For text-to-speech, the metric is FTTS — first-byte time from the LLM’s first token to the first audio sample. Equally important is voice naturalness (MOS). Flash v2.5 wins both axes for our use cases. The one caveat is region proximity: we route Mumbai traffic through the US endpoint today, which adds ~250 ms of network latency on top of the ~200 ms model-inference TTFB.
| Metric | ElevenLabs Flash v2.5 [In Use] | Deepgram Aura-2 |
|---|---|---|
| TTFB — model inference | ~200 ms | ~250 ms |
| TTFB — India via US endpoint | ~478 ms | ~250 ms |
| MOS quality | 4.5–4.8 (human-like) | Not published |
When ElevenLabs APAC GA lands, the Mumbai VART profile improves automatically. If the gap persists for any specific deployment, Deepgram Aura-2 is our pre-validated fallback for APAC traffic.
Inside the Hot Path: Agent Orchestration under Load
The most interesting bottlenecks aren’t where you’d expect. The SFU is fine. The LLM provider is fine. The compression happens inside the two services that sit between them. The Agent-Service runs the agentic orchestration: conversation state, tool calls, traces, the loop that turns a transcript into the next agent action. The LLM calls from the Agent-Service then flow through the LLM Router, which combines model routing with our Model Aggregator — a thin service that manages provider API keys and transforms requests into a uniform OpenAI-compatible format.
With LLM Router pods and Agent Orchestrator pods sized appropriately, we sustain 1,000 concurrent calls across 3,000 requests with zero failures at 40.7 calls/sec. The LLM provider itself contributes only a small fraction of that median; the bulk is orchestration overhead — routing, key management, request transformation, and the agentic loop.
The lesson we learned the hard way: pod sizing matters
The first time we ran the Model Aggregator portion of the LLM Router at 1,000 concurrency on its original sizing (1 core / 1.5 GB × 3 pods), it broke spectacularly: 33.75% failure rate, two pods restarting under resource exhaustion, a long tail well above 30 s. Doubling each pod to 2 cores / 3 GB resolved it cleanly. Same code, same traffic, completely different outcome.
| Concurrency | 1 core × 3 pods | 2 cores × 3 pods | Outcome |
|---|---|---|---|
| 200 | stable, slow | −44% mean TTFT | Both stable |
| 500 | stable, slow | −38% mean TTFT | Both stable |
| 1,000 | 33.75% failures · pod restarts | 0 failures · +138% throughput | Clean win |
At 100 concurrency, the LLM provider contributes ~36% of the 1.20 s median TTFT (~430 ms). The remaining ~64% (~770 ms) is orchestration overhead from the agentic loop, model routing, and request transformation through the Model Aggregator. That’s good news: the overhead sits in our code, on our infrastructure, which means we can keep cutting it.
Naturalness: Barge-In and Recovery
Latency makes voice agents fast. Barge-in is what makes them feel human. If a caller starts speaking while the agent is mid-sentence, a natural agent stops quickly, listens, and responds with a new answer. We measured this end-to-end across 20 sequential runs on our production stack.
The total spread across 20 runs was just 203 ms — p95 sat 31 ms above p50, p99 within 88 ms — pointing to a well-tuned VAD and TTS-cancellation pipeline with no significant tail. The barge-in pipeline includes a 300-ms silence-confirmation window that’s deliberately conservative; the underlying audio cut-off reaction is closer to 250–400 ms.
Recovery shares the same STT → LLM → TTS path as a normal turn, so its variance tracks the agent-pipeline characteristics in Section 07 — the cleaner we make the agent orchestration and LLM Router, the cleaner barge-in recovery feels.
The hardest UX failure mode in voice agents is the agent talking over the user. A consistent ~600 ms cut-off — measured across 20 runs with a 31 ms p95–p50 spread — is what lets a SimplAI voice agent feel like a person who’s actually listening, not a TTS engine that won’t stop.
Capacity Plan: 1,000 Concurrent Calls
Putting it all together, here’s what it takes to run 1,000 concurrent voice conversations on the SimplAI stack — sized from the actual measurements above, with realistic headroom.
| Layer | Pods | Per-pod Resources | Notes |
|---|---|---|---|
| LiveKit SFU | 3 – 5 | 1 c req / 4 c limit · 4 GB | HPA at 80% CPU; 3 pods at 1,000 rooms with burst headroom |
| Voice-Agent Worker | ~85 | 4 cores · 3 GB | ~12 calls/pod; binding constraint for SIP. WebRTC scales similarly |
| LLM Router | 3 – 4 | 2 cores · 3 GB | Sustained 1,000 conc. with zero failures at this sizing |
| Agent-Service | 3 – 5 | 3 cores · 5 GB | I/O-bound; throughput scales near-linearly with replicas |
| STT (Deepgram) | SaaS | Concurrency quota | Pre-provisioned per region with vendor |
| TTS (ElevenLabs) | SaaS | Concurrency quota | APAC routing fallback ready |
Numbers above assume same-region deployment per our default topology. Voice-agent worker count dominates the cost line — and is the layer most amenable to next-quarter optimization (see Section 10).
What We Ship Next
Numbers like these are a checkpoint, not a finish line. The road map for the next two quarters keeps the same north stars — sub-second VART, human-feel barge-in, no tail failures at 1,000+ concurrent — and pushes them further.
Most of the remaining latency in the LLM Router is orchestration overhead — model resolution, routing, request shaping. We’re refactoring the hot path with prefetched config, fewer cross-service hops, and aggressive connection pooling. Target: median TTFT < 500 ms, P95 < 1 s, at 1,000 concurrent.
Today’s ~12 calls/pod at 4 cores is a clean linear-scaling number, but it’s also the dominant cost line at 1,000 concurrency. Profiling work on the worker hot loop — reducing per-call goroutine cost, batching control-plane messaging — targets ~20–25 calls/pod in the next release.
The Mumbai TTS gap is the only place where geography still costs us. We’re piloting ElevenLabs APAC as it rolls into GA, plus a per-tenant policy that auto-fails over to Deepgram Aura-2 when network TTFB exceeds threshold. The goal is same VART profile in APAC as in NA.
Today’s 0.6 s p50 is in the “Good” band; sub-300 ms is what we want — the “feels like interrupting a human” range. We’re lowering the silence-confirmation window where signal quality allows, and exploring on-device VAD to skip a network hop on the cancel path.
Every benchmark above is being lifted into our CI: a weekly regression run that drives 100 → 1,000 concurrent calls, captures VART and barge-in distributions, and gates production deploys on no regression vs. the previous baseline. Performance becomes a property we ship, not an audit we run.
The SimplAI Commitment
Voice is the highest-bar interface software has — there’s nowhere to hide a 4-second pause or a robotic interruption. The stack we’ve built holds 1,000 concurrent calls with zero packet loss, hits a 1.80-second VART end-to-end against real-world benchmarked scenarios (not demos), and lets the agent stop talking in 600 ms when a caller chimes in. Whether you’re deploying outbound calling agents at scale or embedding a conversational agent in your product, the same infrastructure carries the call.
We’re committed to keeping that bar moving. The benchmarks in this post are public so customers, partners, and our own teams can hold us to them. The next set of numbers ship with the next release.
Want to see SimplAI Voice in your stack?
Talk to our team about same-region deployment, your concurrency targets, and your VART budget. We’ll size it together.