Header Logo

Comparing STUN vs TURN for Protoface Realtime Avatar Streaming: When to Use Each

Comparing STUN vs TURN for Protoface Realtime Avatar Streaming: When to Use Each

STUN vs TURN for Protoface avatar streaming: ICE, relay fallback, latency, cost, and reliability in WebRTC realtime apps.

Introduction


When you stream a realtime avatar, you are not just “sending video.” You are negotiating network paths for media, establishing a low-latency transport, and often punching through NATs and firewalls in environments you do not control. In practice, the first question is usually not “how do I render a face?” but “how do the two peers actually find a path that works reliably?”


That is where STUN and TURN come in. They are related, but they solve different problems. If you are building a voice agent, conversational video agent, or embedded web avatar with Protoface, understanding the difference matters because it directly affects connection success rate, latency, bandwidth cost, and failure modes.


By the end of this post, you should be able to answer three questions:


  • What STUN does in a WebRTC-style media setup, and what it does not do.

  • When TURN is required, and why it is more expensive than STUN.

  • How to choose the right fallback strategy for realtime avatar streaming without overengineering it.


STUN: discover the path, don’t relay the media


STUN is the lighter-weight part of the connectivity stack. A STUN server helps a client discover its public-facing network address as seen from outside the NAT. In WebRTC, that information is used to gather ICE candidates so peers can try direct connectivity.


Important detail: STUN does not carry your media in the steady state. It helps establish connectivity. Once a direct path is found, audio/video usually flows peer-to-peer or peer-to-media-server without the STUN server sitting in the media path.


That makes STUN attractive when you want the lowest possible latency and bandwidth overhead. For realtime avatars, that matters because you are often syncing:


  • incoming user speech,

  • ASR/LLM turn-taking,

  • avatar lip sync and facial motion,

  • and sometimes outbound video frames.


If you can establish a direct or otherwise efficient path, you keep the media path short and predictable.


The limitation is the one everyone eventually hits: STUN can help you discover addresses, but it cannot force a direct path through restrictive NATs, symmetric NATs, enterprise firewalls, or networks that block UDP. If the path cannot be opened directly, STUN alone will not save you.


TURN: relay when direct connectivity fails


TURN is the fallback that actually carries traffic when peers cannot connect directly. A TURN server relays media between endpoints, so the client sends audio/video to TURN and TURN forwards it onward.


This is more expensive in every sense:


  • Bandwidth: every media packet traverses the relay, often doubling egress.

  • Latency: the relay adds an extra network hop.

  • Operational cost: TURN infrastructure must scale with traffic volume.


But TURN is also what makes realtime systems robust in the real world. If your users are on corporate Wi-Fi, mobile carrier NATs, locked-down browsers, hotel networks, or environments with aggressive UDP filtering, TURN is often the difference between “works sometimes” and “works reliably.”


For avatar streaming, TURN is usually not the happy path; it is the insurance policy. You want as many sessions as possible to connect directly, but you need TURN so the rest do not fail silently.


How to think about the trade-off in avatar streaming


The practical decision is not “STUN or TURN?” It is usually “STUN first, TURN as a fallback.” In modern RTC systems, ICE will try a set of candidate paths in order of preference. Typical priority looks like this:


  1. Direct host or server-reflexive candidates discovered via STUN.

  2. Relayed candidates via TURN when direct connectivity is not possible.


For a realtime avatar, the choice affects the user experience in a few concrete ways:


  • Startup time: ICE gathering and candidate checks can delay first frame if the network is slow or blocked.

  • Choppiness: poor paths increase jitter and packet loss, which is immediately visible in a talking face.

  • Audio-video sync: relays and unstable paths can make lip sync feel off even if the AI is generating content correctly.

  • Cost model: a system that relies heavily on TURN may be materially more expensive at scale than one that usually connects directly.


There is also a deployment reality: if your avatar is served from a browser via WebRTC, you do not control the end-user network. You need a setup that is resilient by default. That usually means:


  • use STUN for discovery and direct-path attempts,

  • configure TURN for fallback,

  • monitor relay usage as an operational signal.


What to look for in a real integration


If you are integrating an avatar into a voice agent or conversational app, your transport should be treated like any other production dependency. A few things are worth checking early:


1. Is media actually WebRTC?
If yes, ICE/STUN/TURN are likely part of the path. If no, you may be using a different media stack with different relay semantics.


2. Where does the avatar live?
If the avatar is in the browser, network variability is high and TURN becomes important. If the avatar is inside a managed service or media server, you still may need TURN for the browser edge, but the topology changes.


3. Is the failure mode obvious?
A bad configuration should fail loudly: no media, ICE disconnected, or explicit timeout. Silent degradation is what makes these bugs painful.


4. Do you have observability?
Track candidate type, connection state, and relay rate. If relay usage spikes, that can indicate a client network issue or a misconfiguration in your STUN/TURN setup.


Practical debugging patterns


When a session fails to connect, reduce the problem into layers:


  1. Signaling: did the peers exchange offers/answers and ICE candidates?

  2. ICE gathering: did STUN return server-reflexive candidates?

  3. Connectivity checks: did direct candidate pairs succeed?

  4. Relay fallback: did TURN credentials work, and was the relay reachable?


If signaling is fine but ICE never connects, the issue is often network policy rather than application code. A few common causes:


  • UDP blocked entirely.

  • TURN server unreachable from the client region.

  • Incorrect TURN credentials or allocation lifetime.

  • Overly strict firewall rules on the browser or host side.


For testing, you want at least one environment that simulates a hostile network: VPN on, corporate-style firewall rules, or a mobile hotspot. If your avatar works there, you are in much better shape.


How Protoface fits in


In a Protoface deployment, this transport logic is mostly something you inherit from the media stack around the avatar, not something you hand-roll from scratch. That is especially true if you are using the LiveKit Agents plugin, where the avatar is dropped into an existing realtime voice-agent pipeline and must stay synchronized with speech. In that setup, candidate gathering and relay fallback are part of making the end-to-end experience reliable rather than a separate concern.


A minimal LiveKit-side integration typically looks like this at the application level, while the exact session and media fields live in the docs:


from livekit.plugins.protoface import ProtofaceAvatar

agent.add_participant(avatar)
from livekit.plugins.protoface import ProtofaceAvatar

agent.add_participant(avatar)
from livekit.plugins.protoface import ProtofaceAvatar

agent.add_participant(avatar)


If you are wiring sessions directly, the REST API is also available for managing avatars and realtime sessions. For example, creating a session would be done with a bearer token from your backend, not from the browser:


curl -X POST https://api.protoface.com/... \
-d '{"avatar_id":"...","voice":"..."}'
curl -X POST https://api.protoface.com/... \
-d '{"avatar_id":"...","voice":"..."}'
curl -X POST https://api.protoface.com/... \
-d '{"avatar_id":"...","voice":"..."}'


The exact request shape depends on the endpoint, but the important architectural point is that network-relevant configuration stays server-side. That is the right place to keep credentials, session policy, and any relay-related settings that need to be controlled centrally. If you are working through the integration details, the docs are the right reference: docs.protoface.com.


Rules of thumb


If you only remember a few things, make them these:


  • Use STUN to discover reachable addresses and try direct connectivity first.

  • Use TURN when you need a relay because the network will not permit a direct path.

  • Expect TURN to increase latency and cost, and monitor how often you use it.

  • For realtime avatars, reliability beats theoretical directness; a slightly slower relay is better than a dead connection.


In other words, STUN is the pathfinder, TURN is the fallback truck, and your job as an engineer is to make sure both are available before users start speaking.


Conclusion


For Protoface-style realtime avatar streaming, STUN and TURN are not competing technologies. They are complementary tools in the connection establishment and media delivery path. STUN gets you to the best possible direct path; TURN keeps sessions alive when the network gets in the way.


If you are building a production avatar experience, treat TURN support as mandatory and STUN as the low-latency default. Then test on real-world networks, watch relay usage, and keep the media path as simple as your deployment allows.


For integration specifics, examples, and the current API shape, start with the documentation at docs.protoface.com and the relevant quickstart or plugin repo for your stack.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.

Add a face to your AI.

No credit card needed.