This page is about the turn budget — the round-trip from silence to first
audio back. If instead the audio is delayed but steady (a fixed offset, or
choppy/robotic playback), that’s a media-plane problem: see
One-way / choppy audio and
MOS, jitter & loss.
Measure before you tune
Turn latency is a chain, and every hop is attributed for you. Open the per-turn latency breakdown for a recent call and read the hop-by-hop split before changing anything. A typical cascaded turn decomposes into:| Hop | What it is | Who owns it |
|---|---|---|
| End-of-turn detection | Trailing silence the runtime waits out before it decides the caller is done | Your turn_detection config |
| Transport in | Caller audio → relay → runtime | Network + transport |
| ASR finalize | Streaming partials → final transcript | ASR provider |
| LLM time-to-first-token | Prompt sent → first token back | LLM provider |
| TTS time-to-first-audio | Text → first synthesized frame | TTS provider |
| Transport out | First agent frame → caller | Network + transport |
Symptom → cause → fix
Read the breakdown and find the dominant hop
Pull up the latency breakdown
for a slow turn. Whichever hop is largest is your target — the rest is noise
until you fix it.
| Symptom (dominant hop) | Likely cause | Fix |
|---|---|---|
| LLM + ASR + TTS each add a round-trip | Cascaded pipeline serializes three separate provider hops | Move to a speech-to-speech provider — one round-trip instead of three |
| One provider hop dominates (ASR or LLM or TTS) | That provider’s own round-trip / region is slow, or it’s non-streaming | Pick a streaming client, a nearer provider region, or a faster model |
| First turn of every call is slow, later turns snappy | Cold model / cold session — the provider connection or self-hosted pod warms up on the first turn | Rely on session prewarm; keep self-hosted pods warm |
| Every hop is a bit slow, tail is spiky (p99 ≫ p50) | Region / relay distance, or a TCP/WebSocket fallback leg | Colocate the media plane near the provider; confirm you’re on QUIC, not the fallback |
| Agent replies feel late but the provider hops are fast | End-of-turn detection is waiting out too much silence | Lower silence_duration_ms |
| Small, constant overhead on phone legs only | Codec transcode / resampling between G.711, PCM16, and Opus | Usually leave it — it’s sub-frame; only matters as codec passthrough for bridges |
Cascade vs speech-to-speech
This is the single biggest lever. A cascaded agent (ASR → LLM → TTS) pays three serialized provider round-trips per turn: the transcript must finalize before the LLM starts, and the LLM must emit text before TTS can synthesize. A speech-to-speech (realtime) agent streams audio straight into one model that emits audio back, collapsing all three into a single bidirectional stream — often the difference between a ~1.2 s and a sub-500 ms turn.Switch to speech-to-speech
When to use a realtime model and how to wire one up. Options include OpenAI
Realtime, Gemini Live, xAI Grok Voice, ElevenLabs Conversational AI, and a
self-hosted realtime model.
Keep a cascade, make it fast
If you need the flexibility of separate ASR/LLM/TTS, the fixes below keep a
cascade competitive.
Provider round-trip
If one hop dominates and it’s an individual provider, the latency is coming from that provider’s own service, not from us. Three fixes, in order of impact:Use streaming clients, not batch
Streaming ASR emits partials and finalizes fast; streaming TTS returns
time-to-first-audio in a few frames instead of after the whole utterance. A
non-streaming HTTP LLM is the worst offender — it returns nothing until the full
response is generated, so the caller waits out the entire completion. Prefer a
streaming or realtime model for any latency-sensitive agent.
Move the provider region closer
Every provider hop crosses the network twice. If your agent runs in one region
and the provider’s endpoint is in another, that geography is baked into every
turn. Point the provider at its nearest region to your media plane.
A non-streaming LLM also breaks clean barge-in: the runtime can silence playback
the instant the caller interrupts, but the provider still finishes — and bills —
the full response. See
Turn detection & barge-in for why.
Region and relay distance
Media rides QUIC / media-over-QUIC to the relay atrelay.telequick.dev, then
on to your agent runtime and providers. Two distances matter, and they add up:
- Caller → relay. Callers connect to the nearest edge; browser and app legs auto-reconnect with capped backoff if a path degrades. This hop is usually small.
- Runtime ↔ provider. The larger, more variable cost. If your agent runtime and your ASR/LLM/TTS providers sit in different regions, every turn pays that crossing three times over on a cascade.
Cold models
The first turn of a call can be slow while everything downstream warms up. The runtime already fights this for you:- Session prewarm. For realtime agents, the runtime opens and warms the provider session during the inbound INVITE / SDP exchange — before the caller even finishes connecting — so the first turn doesn’t pay connection setup.
- Continuous prefill (self-hosted). A warm, continuously-prefilled self-hosted realtime model can return time-to-first-audio in roughly 0–15 ms once the session is live.
Self-hosted inference
How the on-prem inference control plane routes to your model pods, and how to
keep capacity warm.
End-of-turn detection
Sometimes the providers are fast and the agent still feels late — because the runtime is politely waiting out silence before it decides the caller is done. That wait issilence_duration_ms (default 500). Every millisecond here is
added to the front of every turn.
- Lower it (~300 ms) for snappier replies with terse callers.
- Raise it (~800 ms) for callers who pause mid-thought, if the agent keeps cutting them off.
Turn detection & barge-in
The full set of end-of-turn and barge-in timings, including
silence_duration_ms,
prefix_padding_ms, and hold-and-confirm barge-in.Codec transcode
Phone legs arrive as G.711 (µ-law / A-law); the agent bus runs on narrowband PCM16; browser and app legs use Opus. The runtime transcodes and resamples between these in-process. In practice this is sub-frame and not your latency problem — chasing it is almost never worth it. The one place codec choice does matter is bridging: when you can keep the same codec end to end — for example passing Twilio Media Streams µ-law straight through to a PCMU trunk — you skip transcode entirely on that path. See Codecs and Migrate from Twilio for the passthrough fast path.Related
Latency breakdown
The hop-by-hop attribution to read first — where every millisecond of a turn
actually goes.
Choose a runtime
Cascade vs speech-to-speech vs bring-your-own, and the latency each implies.
Barge-in not working
The other half of turn timing — when the agent won’t yield to the caller.
MOS, jitter & loss
When the problem is audio quality rather than turn speed.