Engineering

Why the Call Drops at Second 47

Codec mismatches, TURN relay latency, and calls that die at the same second every time. Notes from the messy layer where voice infrastructure meets conversation logic.

Most days building SIPRTC look like this: a codec mismatch nobody can reproduce, latency hiding somewhere in a TURN relay, and a call that drops at second 47. Not second 46. Not sometimes. Forty-seven.

If you have worked on voice infrastructure you already know the feeling. If you are about to, here is what the failure modes actually look like, and why the oddly specific ones are usually the easiest to solve.

The call that dies at the same second every time

A random drop is a network problem. A drop at a consistent second is a timer, and timers are findable.

Three usual suspects:

SIP session timers (1). Both sides agree a Session-Expires interval and one of them refreshes the session with a re-INVITE or UPDATE before it lapses. If the refresh never arrives — a proxy stripping the header, a refresher role both sides think the other owns — the session is torn down on schedule. Look for a call that dies at almost exactly half your negotiated interval, because that is often when the first refresh was due.

NAT binding expiry. Consumer routers commonly drop idle UDP mappings after 30 seconds to a couple of minutes. If media is flowing this rarely bites; if you have one-way audio or a hold period, the return path can quietly disappear while signalling still looks healthy.

Media-plane inactivity timeouts. Media servers and session border controllers drop calls with no RTP for N seconds. This is the one that catches teams doing voice AI, because a long model response or a stalled TTS stream can look exactly like a dead call to whatever is counting packets.

The debugging order that saves time: check whether signalling or media died first. If your SIP dialogue is still alive when the audio stops, it is a media problem and you can ignore half the stack.

Codec mismatches that only show up in production

Codec negotiation looks solved until you put a real carrier on one end and a browser on the other. WebRTC wants Opus. The PSTN gives you G.711 or G.729. Something has to transcode, and transcoding is where CPU, latency and quality go to argue.

The failures that eat afternoons:

  • Asymmetric offers. Both sides list Opus, both sides list PCMU, and they agree on different ones in each direction because the answer reordered the payload types.
  • DTMF taking three different routes. RFC 4733 telephone-events, SIP INFO, and inband tones are three separate mechanisms, and the IVR that works on your softphone can be deaf to the one your carrier sends.
  • Sample-rate drift. Opus at 48 kHz meeting a narrowband leg does not fail loudly. It just sounds slightly wrong, and someone reports "the audio is a bit off" three weeks later.
  • Packetisation mismatch. 20 ms versus 30 ms ptime is legal on both sides and still adds jitter you did not plan for.

None of these throw an error. They produce a call that technically connects and subtly does not work, which is worse.

TURN relays and the latency you did not budget for

ICE tries direct first, then server-reflexive, then relay. When it lands on TURN every packet takes an extra hop through your relay, and if that relay is in the wrong region the extra hop is not 5 ms, it is 80.

Two things worth checking before you blame the model for slow responses:

  1. Where did ICE actually land? Not what you configured — what the connection selected. A relay candidate winning when you expected host-to-host is a good explanation for latency that appears on some networks and not others.
  2. How far is the relay from both ends? A relay chosen by round-robin rather than proximity can route a call between two people in the same city through another continent.

Jitter buffers then add their own delay on top, adaptively, and adaptive is another word for "varies by call".

The messy layer: where infrastructure meets conversation

This is the part that has no clean abstraction, and it is where voice AI projects actually get hard.

Turn-taking. Deciding someone has finished speaking is a guess. End too early and the agent interrupts. End too late and the pause feels wrong — humans start expecting a reply about 200 ms after we stop talking, and notice when it does not come. Endpointing thresholds that feel natural in English at a desk feel broken on a noisy mobile line.

Barge-in. Letting the caller interrupt means killing TTS playback mid-word and flushing whatever is queued. Get the echo cancellation wrong and the agent interrupts itself, hearing its own output as caller speech.

Latency budget. End-of-speech to first audio out is not one number, it is a chain: endpointing, network to your inference, model time, TTS time-to-first- byte, network back, jitter buffer. Every link is defensible. The sum is what the caller hears.

State that survives a transfer. The moment a call escalates to a human, all the context the agent gathered either moves with it or is re-collected by an irritated person asking the customer to repeat themselves.

Why we ended up building this as one platform

Every problem above crosses a boundary. Codec mismatches live between the carrier and the media server. TURN latency lives between the network and the media path. Turn-taking lives between the media path and the model.

When those layers belong to different vendors, debugging becomes a support-ticket relay race — and the answer that comes back is usually that the problem is on the other side. That is the honest reason SIPRTC runs SIP trunking, WebRTC media, routing and the conversation layer together, and why we let customers deploy it inside their own network and stream live call audio to their own models. Not because bundling is inherently better, but because the seams are where the bugs live and we wanted to own them.

What are you building?

We would like to know more people doing this kind of work: telephony APIs, real-time audio and video, IVR and conversational systems, or anyone wrestling with SIP in production.

If that is you, we would genuinely like to compare notes — including the parts where our approach is wrong. Get in touch, or find us on LinkedIn.

And if you have ever found the actual cause of a drop at second 47, we want to hear it.