WebRTC TURN: Why you NEED it and when you DON'T need it

WebRTC TURN servers are an essential piece of almost any WebRTC deployment. If you aren’t using them, then make sure you have a VERY good reason.

Connecting a WebRTC session is an orchestrated effort done with the assistance of multiple WebRTC servers. The NAT traversal servers in WebRTC are in charge of making sure the media gets properly connected. These servers are STUN and TURN.

Key Takeaways

  • WebRTC TURN servers are vital for connecting sessions when direct connections fail
  • STUN servers help discover public IP addresses; however, TURN servers relay media when users cannot connect directly
  • TURN servers require proper installation and configuration, as misconfigurations can complicate WebRTC connections
  • For testing TURN configurations, blocking UDP and using Google’s Trickle ICE sample can help ensure functionality

Want to connect MORE sessions in your WebRTC application?

I’ve got you covered with this short video minicourse. Just register below and you’ll get the first email immediately.

STUN, TURN and ICE

Before we start, it might be good to quickly explain these three terms, and we’re going to have the simplified version here, focused on WebRTC and the context of servers:

WebRTC STUN server

STUN - STUN servers are used to find the public IP address of the user. They are needed for the majority of the services. It should be noted though that a TURN server acts also as a STUN server when used over UDP transport.

You can find free STUN servers over the internet, which is rather useless… especially if you’re using TURN (because TURN can second as a STUN server).

WebRTC TURN server

TURN - TURN servers relay media when the users can’t reach each other directly. They use lots of bandwidth resources and cannot view the actual media since it is encrypted and they don’t have the encryption keys. You can relay over TURN servers using either UDP, TCP or TLS. What will be used exactly depends on your configuration and the network.

TURN servers are a pain. You need to install and maintain them, deploy them in multiple regions, and pay for them. A common approach is to use a managed service instead of having your own.

🛑 Don’t use free public WebRTC turn servers. You get what you paid for, and remember that TURN costs money. So if you’re not paying for it, the vendor offering it freely isn’t using the best network either…

ICE protocol in WebRTC

ICE - ICE isn’t a server. It is a protocol/algorithm that is used to connect WebRTC entities to one another. It decides if STUN or TURN are needed for the session and when.

In WebRTC, Trickle ICE is used by default, which is meant to make the time to connect a session shorter.

Now that we know a wee bit about these terms and servers, time to see how we use them in WebRTC.

3 ways to connect WebRTC sessions

When connecting a session between two browsers ( peer-to-peer ) in WebRTC, there are 3 different alternatives that might happen.

Connect directly, across the local network

Connecting WebRTC
Connecting WebRTC over a local network

If both devices are on the local network, then there’s no special effort needed to be done to get them connected to each other. If one device has the local IP address of the other device, then they can communicate with each other directly.

Most of the time and for most use cases, this is NOT going to be the case.

Oh, and just because we all love complicating things in WebRTC, you might bump into mDNS addresses instead of private IP Addresses…

Connect directly, over the internet, with public IP addresses

STUN
Connecting WebRTC directly using public IP address obtained via STUN

When the devices aren’t inside the same local network, then the way to reach each other can only be done through public IP addresses. Since our devices don’t know their public IP addresses, they need to ask for it first.

This is where STUN comes in. It enables the devices to ask a STUN server “what is my public IP address?”

Assuming all is well, and there are no other blocking factors, then the public IP address is enough to get the devices to connect to each other. Common lore indicates that around 80% of all connections can be resolved by either using the local IP address or by use of STUN and public IP addresses.

Route the media through a WebRTC TURN server

Public IP
Connecting WebRTC by using TURN to relay the media

Knowing the public IP address is great, but it might not be enough.

There are multiple reasons for this, one of them being that the NAT and firewall devices in use are not allowing such direct traffic to take place. In such cases, we route the data through an intermediary public server called TURN.

Since we are routing the data, it is an expensive endeavor compared to the other approaches - it has bandwidth costs associated with it and it is why Google won’t ever offer a free TURN server.

Transport protocols and WebRTC TURN servers

TURN comes in 3 different flavors in WebRTC (6 if you want to be more accurate).

TURN Connectivity
How testRTC checks and explains connectivity alternatives of TURN servers in qualityRTC

You can relay your WebRTC data over TURN by going either over IPv4 or IPv6, where IPv4 is (still) the more popular choice.

Then there’s the choice of connecting over UDP, TCP or TLS.

UDP would work best here because WebRTC knows best when and how to manage network congestion and if to use retransmissions. Since it doesn’t always work, it might require the use of TCP or even TLS.

Which type of a connection would you end up with? You won’t really know until the connection gets established, so you’ll need to have all your options opened.

When is a TURN server needed in WebRTC?

That’s easy. Whenever there can’t be a direct connection between the two devices.

For peer to peer, you will need to install and run a TURN server.

And you’d rather use UDP than TCP and you’d rather use TCP than TLS.

TURN UDP
Try direct, then TURN/UDP, then TURN/TCP and finally TURN/TLS

The illustration above shows our “priorities” in how we’d like a session to connect in a peer to peer scenario.

If you are connecting your devices to a media server (be it an SFU for group calling or any other type of a server), you’ll still need a TURN server.

Why? Because some firewalls block certain types of traffic. Many just block UDP. Some may even block TCP.

With a typical WebRTC media server, my suggestion is to configure TURN/TCP and TURN/TLS transports and remove the TURN/UDP option - since you have direct access to the public IP address of the media server, there’s no point in using TURN/UDP.

💡 It seems there are cases where random ports might be blocked while UDP port 443 left open. Might make sense to use TURN/UDP even with the use of media servers

TURN TCP
Try direct to server, then TURN/TCP and finally TURN/TLS

The illustration above shows our “priorities” in how we’d like a session to connect with a media server.

What about ICE-TCP?

There’s a mechanism called ICE-TCP that can be used in WebRTC. In essence, it enables a media server to provide in the SDP an ICE candidate using a TCP transport. This means the media server will actively wait on a TCP port for an incoming connection from the device.

It used to be a Chrome feature, but now it is available in all web browsers that support WebRTC.

This makes the use of TURN/TCP unnecessary, but will still leave us with the need of TURN/TLS.

ICE - TCP
Try direct UDP to server, then direct ICE-TCP to server and finally TURN/TLS

The illustration above shows our “priorities” in how we’d like a session to connect with ICE-TCP turned on.

The elusive (mis)configuration of TURN servers in WebRTC

Configuring TURN servers in WebRTC isn’t an easy task. The reason isn’t that this is rocket science. It is more due to the fact that checking a configuration to ensure it works properly isn’t that simple.

We are used to testing things locally. Right?

Here’s the challenge - in WebRTC, trying it on your machine, or with your machine and the one next to it - will ALWAYS WORK. Why? Because they connect directly, across the local network. This means TURN isn’t even necessary or used in such a case. So you never test that path in your code/configuration.

What can you do about it?

  1. Be aware of this
  2. Use the sample provided by Google for Trickle ICE testing. It won’t check everything, but it will validate that you’ve at least installed and configured the TURN server semi-properly
  3. Block UDP on the machine in your local network and then try to connect a session to another machine on your local network. Make sure it went over TURN/TCP relay (check webrtc-internals dump for that)

The above things can be done locally and repeatedly, so start there. Once you get this to work, move towards the internet to check it there.

And if this is giving you a headache, then your best bet is simply to use a managed WebRTC TURN service and be done with it.

Quick facts

✅ Do you need a TURN server if you connect your sessions to a WebRTC media server?

That depends. Some WebRTC media servers support ICE-TCP, which can be considered as an alternative for TURN/TCP and TURN/TLS.
If your media server doesn't support ICE-TCP, you will likely need TURN servers with TCP and TLS configured.

✅ Do media servers need to have WebRTC TURN server configuration?

Usually not. In most cases you will be installing media servers with direct internet access on a public IP address. This means that having TURN configured only on the WebRTC client side is enough.

✅ How do you test a TURN server configuration for your application?

An easy way is to block UDP traffic and see if your WebRTC client can still connect. Another one is to use Google’s Trickle ICE sample.

Tsahi Levent-Levi

Tsahi Levent-Levi

Independent WebRTC analyst. I help companies ship real-time communications they can actually monitor. 20+ years in the comms space, last 13 focused on WebRTC.

More about Tsahi →