- 01Perceived response time is dominated by the endpointing delay — a configured wait, not a processing cost.
- 02Optimising inference on an agent whose latency is endpointing produces no measurable improvement.
- 03Turn detection has several modes with real tradeoffs: VAD is fastest, a turn-detector model is most natural.
- 04Barge-in done naively cannot distinguish an interruption from “mm-hmm”, so the agent never finishes a sentence.
- 05Provider docs publish limits, not latency. Measure end to end on your own path and report percentiles.
The pipeline
Every stage adds delay and every stage is separately replaceable, which is why the category has so many vendors — each one occupies a different subset of that chain. Knowing which stage a product covers is more useful than knowing its feature list.
| Stage | Dominant cost | Tunable? |
|---|---|---|
| Transport | Network path and jitter buffering | Partly — codec, region |
| Turn detection | A deliberate wait for silence | Yes — this is the big one |
| Speech-to-text | Streaming finalisation of the last words | Somewhat |
| Agent loop | Model latency plus any tool calls | Yes — model, effort, tools |
| Text-to-speech | Time to first audio chunk | Somewhat — model, streaming |
| Playback | Buffer depth before audio starts | Yes, at some risk |
Note that only one row is a decision rather than a computation. That is the row this article is mostly about, because it is both the largest contributor in most deployments and the one teams overlook — you cannot profile it, since nothing is running.
Where the latency actually is
The reason it exists is that humans pause mid-sentence. Someone saying “I need to reschedule my appointment… to next Tuesday” produces a silence in the middle that is not the end of their turn. Cut the wait too short and the agent answers the first half. Make it long enough to be safe and every exchange feels sluggish.
“You cannot profile a deliberate wait. It is the largest number in the budget and the only one that never shows up in a flame graph.”
Frameworks expose it directly. LiveKit’s endpointing takes a min_delay and max_delay, and its Python SDK also offers dynamic endpointing — adapting the delay within that range based on the pause statistics of the current session. That is the right shape of solution: a caller who speaks in long deliberate phrases and one who fires short answers should not get the same fixed wait.
- The diagnosis to run first
- Before optimising anything, log the timestamp of the caller’s last speech frame and the timestamp of the first byte of agent audio, then subtract every downstream processing stage you can measure. What remains is your endpointing delay. If it dominates, no model change will help.
Turn detection modes
The choice is a latency-versus-naturalness dial, and unlike most such dials it has a clear default.
| Mode | How it decides | Choose when |
|---|---|---|
| Turn-detector model | Audio + text models predict end-of-turn from meaning and acoustics | Default. Most natural conversation |
| VAD only | Speech activity alone, no semantics | Minimum latency, or an unsupported language |
| STT endpointing | The transcription provider signals the turn boundary | Your STT provider does this well |
| Realtime model | Server-side detection inside the speech model | You're using a realtime speech API end to end |
| Manual | Your application decides | Push-to-talk, or a UI with an explicit send |
The model-based option is worth understanding rather than just enabling. A pure VAD decides on silence; a turn-detector model decides on whether the sentence sounds finished. “I’d like to book an appointment for” is acoustically complete and semantically obviously not, and only the second approach can tell.
Manual mode deserves a mention because it is under-used. For confirmations of consequential actions, an explicit turn boundary removes an entire class of error — and if the action needs approval anyway, the approval and the turn boundary can be the same interaction. That intersects with where the authority boundary sits.
Barge-in, and the backchannel problem
This is the single most common reason a voice agent feels broken to someone who has never used one, because backchannelling is involuntary. Callers do not know they are doing it, so from their side the agent simply keeps stopping for no reason.
Good frameworks treat it as a classification problem rather than a threshold. LiveKit’s interruption handling has an adaptive mode — the default on their cloud — described explicitly as distinguishing true interruptions from conversational backchannelling, alongside a plain vad mode that triggers on speech start/stop.
The last pair is the part worth copying even if you build your own. A misclassified backchannel that permanently silences the agent leaves the caller in dead air; the same misclassification with a resume path is a barely perceptible stumble. Recovering from being wrong is more valuable than being right slightly more often.
Two more controls worth setting
discard_audio_if_uninterruptible drops buffered audio while the agent is in a state that cannot be interrupted — without it, speech captured during an uninterruptible passage arrives afterwards and gets acted on late, which produces the agent answering something the caller said thirty seconds ago.
And a cap on caller turn length — a maximum word count or duration — with a handler for exceeding it. Without one, a caller who monologues produces an unbounded transcript and an agent that never gets a turn. The documented default behaviour on exceeding it is to generate a reply that cannot itself be interrupted, which is exactly right: the agent needs one uninterrupted sentence to regain the floor.
Repair
The failure mode to design against is confident action on a misheard value. An agent that books Tuesday when the caller said Thursday has done something worse than failing, because it will report success.
| Value type | Strategy |
|---|---|
| Consequential and enumerable (a date, a slot) | Read it back and require confirmation before acting |
| High-entropy (name, email, reference) | Spell or digit-group it back; expect correction |
| Low-stakes (a preference, a note) | Accept it; correction can happen later |
| Anything irreversible | Confirm, and gate behind a human where the cost justifies it |
Note the interaction with turn detection: a read-back confirmation is exactly the moment a caller interrupts, because they heard the wrong value and reacted. So confirmation prompts should be interruptible even if other agent speech is not — the interruption there is a signal, not noise.
Telephony changes the numbers
LiveKit’s telephony-optimised example for a realtime model is concrete about the direction: a detection threshold of 0.7 described as less sensitive for noisy phone audio, prefix_padding_ms of 300, and silence_duration_ms of 400 described as a tighter window for snappier turn closing.
// Direction of travel for phone audio, not a universal setting:
// raise the detection threshold → fewer false triggers on line noise
// tighten the silence window → snappier turn closing
{
threshold: 0.7, // less sensitive than a clean-mic default
prefix_padding_ms: 300, // audio retained before detected speech
silence_duration_ms: 400, // silence before the turn is considered over
}The caption matters. These are documented examples for one provider pairing, and the correct values depend on your carrier path, your codec, your callers and your domain. A collections call and a restaurant booking do not want the same patience.
One protocol-level constraint worth knowing before designing session handling: for conversational use, providers may require a single WebSocket per conversation, and voice settings can be fixed at connection time. Deepgram’s streaming TTS documents both, along with hard limits — 2,000 characters per request for Aura models, a throughput cap of 2,400 characters per minute, a flush limit of 20 in any 60 seconds, and a 60-minute connection timeout. Those are the numbers that break a long-running call, and none of them are latency.
Build on infrastructure or buy a platform
| Platform | Infrastructure | |
|---|---|---|
| Time to first call | Days | Weeks |
| Control of turn-taking | Whatever is exposed | Complete — it's your pipeline |
| Per-minute cost | Bundled margin | Component cost plus your ops |
| Where the differentiation lives | Your prompts and integrations | Also the conversation mechanics |
The honest observation is that most teams should start on a platform, and that the reason to leave is almost never a feature — it is that the thing making calls feel human turns out to be endpointing and interruption tuning, and at some point you need finer control of both than a platform exposes.
Which is worth knowing at the start, because it argues for keeping your agent logic, tools and governance outside whatever platform you pick. The conversational layer is the part you might replace; the tool, governance and evidence layers should not have to move with it.
Measure it yourself
Four measurements, all taken from the caller’s perspective rather than from inside a service:
The second is the one that redirects the work. Teams routinely spend a sprint on model latency and find the endpointing wait was three-quarters of the number — at which point a configuration change delivers more than the sprint did.
Percentiles rather than averages, because voice is judged on the bad calls. An agent that is fast on average and occasionally pauses for three seconds is experienced as an agent that pauses for three seconds, and the mean will tell you it is fine.
Finally, instrument the interruption counters as first-class metrics rather than debug logs. False interruptions and missed interruptions are the two numbers that most closely track whether callers find the thing pleasant, and neither appears in any latency dashboard.
Frequently asked questions
What is in a voice agent stack?
Transport carrying audio, voice activity detection, turn detection deciding when the caller finished, speech-to-text, the agent loop with its tools, text-to-speech, and playback — plus an interruption path that can stop generation and playback mid-sentence. Each stage adds latency and each is separately replaceable.
What actually causes voice agent latency?
Usually the endpointing delay — the deliberate wait after the caller stops speaking before the system decides the turn is over. It is a configured pause rather than a processing cost, which is why teams optimising inference often see no improvement. Reduce it and the agent feels fast but interrupts people; raise it and it feels slow but polite.
What is barge-in?
Barge-in is the caller interrupting the agent mid-speech and the agent stopping to listen. Implementing it well means distinguishing a genuine interruption from backchannelling — the “mm-hmm” and “right” that mean keep going. Treating every sound as an interruption produces an agent that cannot finish a sentence.
How do you stop a voice agent being interrupted by “mm-hmm”?
Use an interruption mode that classifies rather than one that triggers on any speech, and set minimum thresholds — a minimum speech duration and a minimum word count before an interruption counts. Frameworks also support treating a short burst followed by silence as a false interruption and resuming the agent's speech.
Should I build a voice agent on infrastructure or buy a platform?
Buy if the conversation is a means to an end and you need it working in weeks. Build on infrastructure when the turn-taking behaviour is the product, you need to tune endpointing and interruption per use case, or per-minute economics at your volume outgrow platform pricing.
Where can I find reliable voice agent latency figures?
Not in vendor documentation — provider docs commonly publish limits and protocol details but not time-to-first-byte. Measure end to end on your own network path, with your own audio, at your own concurrency, and report percentiles rather than averages.
Sources
- 01Turn detection and interruptions — LiveKit, 2026
- 02Streaming text to speech — Deepgram, 2026