How ICE & TURN Work
If you’ve ever wondered why some calls sound great and others don’t, the answer is often in ICE — the protocol that finds the best path for media between two endpoints. Understanding ICE helps you diagnose one-way audio, connection failures, and latency issues.The Problem ICE Solves
Two devices want to send audio to each other. But between them:- NAT (Network Address Translation) — Private IPs (192.168.x.x) aren’t reachable from the internet
- Firewalls — Block incoming connections
- Symmetric NAT — Even STUN can’t discover the public mapping
The Three Candidate Types
ICE discovers three types of candidates, in order of preference:1. Host Candidates (Local)
Your device’s local network interfaces (e.g.,192.168.1.105 on WiFi).
- Works when: Both devices are on the same LAN (rare for WebRTC calls)
- Quality: Best — zero extra latency
- Reality: Almost never used for WebRTC calls — both parties are rarely on the same network
2. Server-Reflexive Candidates (srflx) — via STUN
Your public IP, discovered by asking a STUN server (e.g.,203.0.113.5).
How STUN works:
- SDK sends a request to
stun.telnyx.com:3478 - STUN server sees the source IP (your public IP)
- STUN server sends it back: “Your public IP is 203.0.113.5”
- SDK creates a srflx candidate with that IP
- Works when: Your NAT allows inbound traffic to the mapped port (most home/office routers)
- Quality: Good — direct path, minimal extra latency
- Blockers: Symmetric NAT, strict firewalls
3. Relay Candidates — via TURN
An IP address allocated on a TURN server that relays your media (e.g.,64.16.248.1).
How TURN works:
- SDK authenticates with
turn.telnyx.com:3478over UDP or TCP (TURN/TLS on 443 is not currently supported) - TURN server allocates a relay address (e.g.,
64.16.248.1:50000) - All media is sent TO the TURN server, which forwards it to the remote party
- Remote party also sends TO the TURN server, which forwards to you
- Works when: Always — TURN is the fallback that never fails
- Quality: Adds latency (each packet goes through the TURN server) but guarantees connectivity
- Required when: Symmetric NAT, strict corporate firewalls, mobile carriers that block P2P
ICE Candidate Priority
The SDK tries candidates in this priority order:
In practice, most WebRTC calls use srflx (direct) or relay (TURN). Host candidates rarely work because both parties are on different networks.
A common misconception: “If my call uses TURN relay, something is wrong.”False. TURN relay is normal and expected in many network conditions — mobile networks, corporate networks, some ISPs. The question isn’t “is TURN being used?” but “is the TURN server close to me?”
ICE Gathering Process
When a call starts, the SDK gathers candidates in this sequence:Trickle ICE
By default, the SDK uses Trickle ICE — it sends candidates as they’re discovered rather than waiting for all of them:ICE Connectivity Checks
Once both sides have candidates, ICE performs connectivity checks in this order:
If the STUN check fails (e.g., firewall blocks it), ICE tries the next candidate pair until it finds one that works — falling back to TURN relay if necessary.
DTLS — Encrypting Media
After ICE finds a working path, DTLS (Datagram Transport Layer Security) encrypts the media:
DTLS states:
If DTLS is stuck at
connecting, media won’t flow even if ICE connected. This is the #1 cause of one-way audio.TURN Server Selection
Telnyx operates TURN servers in multiple regions:
The SDK automatically selects the nearest TURN server. You can override:
UDP vs TCP TURN
The SDK tries UDP first, falls back to TCP automatically. TURN/TLS on port
443 is not currently supported.
Troubleshooting ICE Issues
STUN fails (error 701)
Cause: Firewall blocksstun.telnyx.com:3478 (UDP)
Result: No srflx candidates — must use relay
Fix: Open UDP 3478 to STUN servers, or accept TURN relay
All ICE fails
Cause: Both STUN and TURN are blocked Result: Call cannot connect — no media path exists Fix: Open access to TURN servers on port3478 (UDP preferred, TCP fallback). TURN/TLS on port 443 is not currently supported.
Relay when srflx should work
Cause: Symmetric NAT — NAT mapping changes per destination Result: STUN-discovered port doesn’t accept inbound from B2BUA-RTC Fix: This is normal; TURN relay is the correct solutionHigh latency on relay
Cause: TURN server is geographically distant Result: 100ms+ added round-trip Fix: ConfigureiceServers to use a closer TURN server
See Also
- Configure Network & Firewall — Firewall rules and IP allowlists
- Debug Call Issues — How to diagnose ICE/TURN problems
- Monitor Call Quality — Check ICE stats in production
- Call State Lifecycle
- How WebRTC Signaling Works