{"id":1065,"date":"2026-05-22T09:46:08","date_gmt":"2026-05-22T02:46:08","guid":{"rendered":"https:\/\/liveapi.com\/blog\/turn-server\/"},"modified":"2026-05-22T09:46:25","modified_gmt":"2026-05-22T02:46:25","slug":"turn-server","status":"publish","type":"post","link":"https:\/\/liveapi.com\/blog\/turn-server\/","title":{"rendered":"What Is a TURN Server? How It Works, Setup, and Use Cases"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">12<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>Roughly 20% of WebRTC sessions can&#8217;t connect peer-to-peer because of strict NAT, corporate firewalls, or symmetric NAT mappings. When that happens, the call drops \u2014 unless you route the media through a TURN server.<\/p>\n<p>A TURN server is the safety net that keeps real-time video, audio, and data flowing when a direct connection between two browsers or apps is blocked. It relays packets through a public host so both peers can reach each other, even when neither one can reach the other directly.<\/p>\n<p>This guide explains what a TURN server is, how it differs from STUN, how the protocol works step-by-step, what ports it uses, how to set one up with Coturn, what it costs to run, and when your project actually needs one. By the end, you&#8217;ll know how to add TURN to a <a href=\"https:\/\/liveapi.com\/blog\/what-is-webrtc\/\" target=\"_blank\">WebRTC<\/a> app \u2014 and when you can skip it entirely by using a different streaming protocol.<\/p>\n<h2>What Is a TURN Server?<\/h2>\n<p>A TURN server is a network relay that forwards media traffic between two devices when they can&#8217;t establish a direct peer-to-peer connection. TURN stands for <strong>Traversal Using Relays around NAT<\/strong>, and the protocol is defined in <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc8656\" target=\"_blank\" rel=\"nofollow\">RFC 8656<\/a>, published by the IETF in 2020 as an update to the earlier RFC 5766.<\/p>\n<p>In plain terms, a TURN server is an internet-reachable host that both peers can connect to. When peer A sends a packet to peer B, it goes to the TURN server first, which then forwards it to peer B. The relay sits in the middle of the media path for the entire session \u2014 every audio, video, and data packet passes through it.<\/p>\n<p>TURN is most commonly used inside the WebRTC stack, where the ICE framework decides whether a session can connect directly or needs a relay. If direct paths fail, ICE falls back to TURN.<\/p>\n<table>\n<thead>\n<tr>\n<th>Attribute<\/th>\n<th>Detail<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Full name<\/td>\n<td>Traversal Using Relays around NAT<\/td>\n<\/tr>\n<tr>\n<td>Standard<\/td>\n<td>RFC 8656 (2020), updates RFC 5766 (2010)<\/td>\n<\/tr>\n<tr>\n<td>Default port<\/td>\n<td>3478 (TCP\/UDP)<\/td>\n<\/tr>\n<tr>\n<td>TLS port<\/td>\n<td>5349<\/td>\n<\/tr>\n<tr>\n<td>Transport<\/td>\n<td>UDP, TCP, TLS, DTLS<\/td>\n<\/tr>\n<tr>\n<td>Authentication<\/td>\n<td>Long-term credentials or REST API auth<\/td>\n<\/tr>\n<tr>\n<td>Primary use<\/td>\n<td>Relay media when peer-to-peer fails<\/td>\n<\/tr>\n<tr>\n<td>Common implementation<\/td>\n<td>Coturn (open source)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A TURN server is <strong>not<\/strong> the same as a media server or <a href=\"https:\/\/liveapi.com\/blog\/webrtc-server\/\" target=\"_blank\">WebRTC server<\/a>. A media server actively processes streams (mixing, recording, transcoding). A TURN server just forwards bytes without inspecting them \u2014 the media stays end-to-end encrypted with DTLS-SRTP, and the relay can&#8217;t decode what&#8217;s flowing through.<\/p>\n<h2>TURN vs STUN vs ICE: How They Fit Together<\/h2>\n<p>Most articles treat TURN as a standalone topic, but TURN only makes sense inside the broader ICE framework. Here&#8217;s how all three work together.<\/p>\n<h3>STUN: Find Your Public IP<\/h3>\n<p>STUN (Session Traversal Utilities for NAT) is a lightweight protocol that lets a device find its own public IP address and port as seen from the internet. The client sends a request to a <a href=\"https:\/\/liveapi.com\/blog\/stun-server\/\" target=\"_blank\">STUN server<\/a> and gets back the public address the server saw.<\/p>\n<p>STUN does <strong>not<\/strong> relay any traffic. It&#8217;s a one-shot lookup. Once both peers know each other&#8217;s public addresses, they try to connect directly.<\/p>\n<h3>TURN: Relay When STUN Fails<\/h3>\n<p>TURN takes over when direct connection attempts fail. The most common reason is symmetric NAT \u2014 a NAT type that assigns a different external port for every destination, making the address discovered by STUN useless for the actual peer.<\/p>\n<p>TURN relays every packet for the entire session. It&#8217;s expensive in bandwidth, but it works when nothing else does.<\/p>\n<h3>ICE: The Decision Maker<\/h3>\n<p>ICE (Interactive Connectivity Establishment) is the framework that tests every possible connection path and picks the best one. It gathers candidates from:<\/p>\n<ul>\n<li>Host (local IP address)<\/li>\n<li>Server-reflexive (public IP via STUN)<\/li>\n<li>Relayed (TURN server allocation)<\/li>\n<\/ul>\n<p>ICE pairs candidates from both peers, runs connectivity checks, and picks the working pair with the lowest priority cost. TURN is always the last resort because it adds latency and bandwidth cost.<\/p>\n<table>\n<thead>\n<tr>\n<th>Component<\/th>\n<th>Purpose<\/th>\n<th>Stays in media path?<\/th>\n<th>When used<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>STUN<\/td>\n<td>Find public IP\/port<\/td>\n<td>No<\/td>\n<td>Always tried first<\/td>\n<\/tr>\n<tr>\n<td>TURN<\/td>\n<td>Relay all media<\/td>\n<td>Yes, for whole session<\/td>\n<td>Fallback when direct fails<\/td>\n<\/tr>\n<tr>\n<td>ICE<\/td>\n<td>Pick best path<\/td>\n<td>N\/A (control protocol)<\/td>\n<td>Always, manages candidates<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For a deeper look at how NAT blocks direct connections, see our guide on <a href=\"https:\/\/liveapi.com\/blog\/nat-traversal\/\" target=\"_blank\">NAT traversal<\/a>.<\/p>\n<h2>How Does a TURN Server Work?<\/h2>\n<p>The TURN protocol uses a four-step allocation and relay process. Here&#8217;s what happens when a WebRTC client connects through TURN.<\/p>\n<h3>Step 1: Allocate a Relay Address<\/h3>\n<p>The client sends an <strong>Allocate<\/strong> request to the TURN server, authenticated with a username and credential. The server reserves a public IP and port \u2014 called the <strong>relayed transport address<\/strong> \u2014 and returns it to the client.<\/p>\n<pre><code>Client \u2192 TURN: Allocate Request (auth, request UDP relay)\nTURN \u2192 Client: Allocate Success (relay address: 198.51.100.10:49321)\n<\/code><\/pre>\n<p>This relay address is what the client will share with its peer as an ICE candidate.<\/p>\n<h3>Step 2: Create Permissions<\/h3>\n<p>By default, the TURN server drops any packet from an unknown peer. The client sends a <strong>CreatePermission<\/strong> request listing the IP addresses of peers it expects to communicate with. The server adds those IPs to its allow list.<\/p>\n<p>Permissions expire after 5 minutes unless refreshed, which protects the relay from being abused as an open proxy.<\/p>\n<h3>Step 3: Send and Receive Data<\/h3>\n<p>Once permissions are set, the client and peer exchange media in one of two ways:<\/p>\n<ul>\n<li><strong>Send\/Data Indications:<\/strong> Each packet carries a 36-byte TURN header identifying the peer. Simple but adds bandwidth overhead.<\/li>\n<li><strong>Channels:<\/strong> The client binds a 16-bit channel number to a peer with <strong>ChannelBind<\/strong>, then uses a 4-byte channel header on later packets. Much more efficient for high-bandwidth media like video.<\/li>\n<\/ul>\n<pre><code>Client \u2192 TURN: Send Indication (peer: 203.0.113.5, payload: media)\nTURN \u2192 Peer: UDP packet from relay address\nPeer  \u2192 TURN: UDP packet to relay address\nTURN \u2192 Client: Data Indication (from peer: 203.0.113.5, payload)\n<\/code><\/pre>\n<h3>Step 4: Refresh and Release<\/h3>\n<p>Allocations have a default lifetime of 10 minutes. The client sends <strong>Refresh<\/strong> requests to extend the allocation as long as the session is active. When the call ends, the client sends a Refresh with lifetime 0 to release the relay address.<\/p>\n<p>This whole cycle is invisible to the application code. A WebRTC developer just passes the TURN server URL into <code>RTCPeerConnection<\/code> configuration, and the browser handles the protocol exchange automatically.<\/p>\n<h2>TURN Server Ports and Transport Protocols<\/h2>\n<p>TURN can run over multiple transports, which matters when your peers sit behind restrictive corporate firewalls.<\/p>\n<table>\n<thead>\n<tr>\n<th>Port<\/th>\n<th>Protocol<\/th>\n<th>Use case<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>3478<\/td>\n<td>UDP<\/td>\n<td>Standard TURN \u2014 lowest overhead, best for media<\/td>\n<\/tr>\n<tr>\n<td>3478<\/td>\n<td>TCP<\/td>\n<td>Fallback when UDP is blocked<\/td>\n<\/tr>\n<tr>\n<td>5349<\/td>\n<td>TLS over TCP<\/td>\n<td>Encrypted, looks like HTTPS to firewalls<\/td>\n<\/tr>\n<tr>\n<td>5349<\/td>\n<td>DTLS over UDP<\/td>\n<td>Encrypted UDP<\/td>\n<\/tr>\n<tr>\n<td>443<\/td>\n<td>TLS<\/td>\n<td>Disguises TURN as web traffic to bypass strict firewalls<\/td>\n<\/tr>\n<tr>\n<td>80<\/td>\n<td>TCP<\/td>\n<td>Last-resort fallback on the standard HTTP port<\/td>\n<\/tr>\n<tr>\n<td>49152\u201365535<\/td>\n<td>UDP<\/td>\n<td>Relay ports allocated dynamically per session<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Production TURN deployments often listen on port 443 with TLS because corporate networks frequently block everything except HTTPS. Running TURN on 443 makes the relay traffic indistinguishable from a normal web connection, which dramatically improves connection success rates.<\/p>\n<p>For real-time media, UDP is always preferred. TCP retransmissions add latency and can cause head-of-line blocking that ruins audio and video quality. TLS-over-TCP is the connection of last resort.<\/p>\n<h2>Why TURN Servers Matter for WebRTC<\/h2>\n<p>Roughly 80% of WebRTC connections succeed without TURN. The remaining 20% \u2014 across enterprise networks, mobile carriers, and certain home routers \u2014 fail without a relay. Here&#8217;s why.<\/p>\n<h3>Symmetric NAT<\/h3>\n<p>Most home routers use <strong>cone NAT<\/strong>, which keeps the same external port mapping for outbound traffic from a given internal port. STUN works because the public address it discovers is the same one a peer can use to send packets back.<\/p>\n<p>Enterprise networks and many mobile carriers use <strong>symmetric NAT<\/strong>, which allocates a new external port for every destination. The address STUN reports is only valid for the STUN server \u2014 it won&#8217;t work for the peer. TURN is required.<\/p>\n<h3>Restrictive Firewalls<\/h3>\n<p>Corporate firewalls often block all UDP traffic outbound, or only allow connections on ports 80 and 443. WebRTC tries UDP first because it has lower latency, but when UDP is blocked, TURN over TLS on 443 is the only path through.<\/p>\n<h3>Mobile Networks<\/h3>\n<p>Cellular carriers use carrier-grade NAT (CGN) that often behaves symmetrically. A WebRTC app that works fine on Wi-Fi can drop the moment a user switches to LTE without TURN configured.<\/p>\n<h3>Privacy<\/h3>\n<p>Some users disable WebRTC IP leaking in their browsers, which forces all candidates through TURN. The relay hides the user&#8217;s real IP from the remote peer.<\/p>\n<p>Without TURN, all of these users see broken calls. With TURN configured, the connection silently falls back to the relay and the user never notices.<\/p>\n<h2>TURN Server Setup with Coturn<\/h2>\n<p>Coturn is the de facto open-source TURN server. It&#8217;s actively maintained on <a href=\"https:\/\/github.com\/coturn\/coturn\" target=\"_blank\" rel=\"nofollow\">GitHub<\/a>, runs on Linux, supports both STUN and TURN, and is what most production deployments are built on.<\/p>\n<p>Here&#8217;s a minimal setup on Ubuntu.<\/p>\n<h3>Install Coturn<\/h3>\n<pre><code>sudo apt update\nsudo apt install coturn\n<\/code><\/pre>\n<p>Enable the service at boot by editing <code>\/etc\/default\/coturn<\/code>:<\/p>\n<pre><code>TURNSERVER_ENABLED=1\n<\/code><\/pre>\n<h3>Configure the Server<\/h3>\n<p>Edit <code>\/etc\/turnserver.conf<\/code> with the basics:<\/p>\n<pre><code>listening-port=3478\ntls-listening-port=5349\nlistening-ip=0.0.0.0\nexternal-ip=YOUR_PUBLIC_IP\nrealm=turn.yourdomain.com\nserver-name=turn.yourdomain.com\nlt-cred-mech\nuser=webrtcuser:webrtcpassword\nmin-port=49152\nmax-port=65535\ncert=\/etc\/letsencrypt\/live\/turn.yourdomain.com\/fullchain.pem\npkey=\/etc\/letsencrypt\/live\/turn.yourdomain.com\/privkey.pem\nlog-file=\/var\/log\/turnserver.log\nfingerprint\nno-multicast-peers\nno-cli\n<\/code><\/pre>\n<p>Key fields:<\/p>\n<ul>\n<li><strong>external-ip:<\/strong> The public IP of the server (required for cloud VMs behind NAT).<\/li>\n<li><strong>realm:<\/strong> Authentication domain \u2014 typically your TURN domain.<\/li>\n<li><strong>lt-cred-mech:<\/strong> Enables long-term credential authentication (required for production).<\/li>\n<li><strong>user:<\/strong> Static user credentials. For real apps, replace this with <code>use-auth-secret<\/code> and time-limited REST API credentials.<\/li>\n<li><strong>min-port \/ max-port:<\/strong> Range of UDP ports for relay allocations. Open these in your firewall.<\/li>\n<\/ul>\n<h3>Open the Firewall<\/h3>\n<p>On the host and any cloud security group, allow:<\/p>\n<ul>\n<li>TCP\/UDP 3478<\/li>\n<li>TCP\/UDP 5349<\/li>\n<li>UDP 49152\u201365535<\/li>\n<\/ul>\n<p>Restart Coturn:<\/p>\n<pre><code>sudo systemctl restart coturn\n<\/code><\/pre>\n<h3>Test Your TURN Server<\/h3>\n<p>Use the <a href=\"https:\/\/webrtc.github.io\/samples\/src\/content\/peerconnection\/trickle-ice\/\" target=\"_blank\" rel=\"nofollow\">Trickle ICE tool<\/a> from the WebRTC samples. Add your TURN URL, username, and credential, then click <strong>Gather candidates<\/strong>. A successful TURN setup returns candidates of type <code>relay<\/code>. If you only see <code>host<\/code> and <code>srflx<\/code>, the relay isn&#8217;t working \u2014 usually a firewall or external-ip misconfiguration.<\/p>\n<h3>Use TURN in a WebRTC Client<\/h3>\n<p>In your browser code, pass the TURN server to <code>RTCPeerConnection<\/code>:<\/p>\n<pre><code>const pc = new RTCPeerConnection({\n  iceServers: [\n    { urls: 'stun:stun.l.google.com:19302' },\n    {\n      urls: [\n        'turn:turn.yourdomain.com:3478?transport=udp',\n        'turn:turn.yourdomain.com:3478?transport=tcp',\n        'turns:turn.yourdomain.com:5349?transport=tcp'\n      ],\n      username: 'webrtcuser',\n      credential: 'webrtcpassword'\n    }\n  ]\n});\n<\/code><\/pre>\n<p>For production, never embed static credentials in client code. Generate short-lived credentials on a backend using the REST API auth pattern (HMAC-signed timestamp + username), or use a managed TURN provider.<\/p>\n<p>For mobile, the same configuration applies \u2014 see our walkthrough on <a href=\"https:\/\/liveapi.com\/blog\/react-native-webrtc\/\" target=\"_blank\">React Native WebRTC<\/a> for client implementation details.<\/p>\n<h2>Managed TURN vs Self-Hosted: Which to Choose<\/h2>\n<p>You have three paths to TURN in production: self-host with Coturn, use a managed TURN service, or build TURN into a larger video platform. Each has trade-offs.<\/p>\n<table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Setup time<\/th>\n<th>Monthly cost (low usage)<\/th>\n<th>Operational burden<\/th>\n<th>Best for<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Self-hosted Coturn<\/td>\n<td>1\u20132 days<\/td>\n<td>$20\u2013$100 VPS<\/td>\n<td>High (security, scaling, monitoring)<\/td>\n<td>Cost-sensitive, predictable load<\/td>\n<\/tr>\n<tr>\n<td>Twilio Network Traversal<\/td>\n<td>Minutes<\/td>\n<td>$0.40\u2013$0.80 \/ GB relayed<\/td>\n<td>None<\/td>\n<td>Variable load, global presence<\/td>\n<\/tr>\n<tr>\n<td>Cloudflare Calls TURN<\/td>\n<td>Minutes<\/td>\n<td>$0.05 \/ GB (1 TB free)<\/td>\n<td>None<\/td>\n<td>High volume, modern stacks<\/td>\n<\/tr>\n<tr>\n<td>Metered TURN<\/td>\n<td>Minutes<\/td>\n<td>$0.40 \/ GB<\/td>\n<td>None<\/td>\n<td>Mid-market, simple pricing<\/td>\n<\/tr>\n<tr>\n<td>Xirsys<\/td>\n<td>Minutes<\/td>\n<td>From $33\/month<\/td>\n<td>None<\/td>\n<td>Multi-region with SLA<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Self-Hosted Coturn<\/h3>\n<p>Cheapest at low scale \u2014 a $20\/month VPS handles thousands of concurrent low-bandwidth sessions. But you own everything: TLS certificate renewal, DDoS protection, kernel tuning, multi-region failover, credential rotation, and abuse monitoring. Misconfigured Coturn servers regularly end up as open relays used by attackers, which gets the IP blocklisted.<\/p>\n<h3>Managed TURN Providers<\/h3>\n<p>Twilio, Cloudflare, Xirsys, and Metered all offer pay-as-you-go TURN. The signup-to-production path is under an hour. You get global anycast endpoints, automatic credential rotation, and abuse protection out of the box. The downside is per-GB pricing \u2014 Twilio charges $0.40\u2013$0.80\/GB depending on region, while Cloudflare prices at $0.05\/GB with 1 TB free monthly. A single 720p video call uses roughly 1\u20132 GB per hour relayed.<\/p>\n<p>For most teams, managed is the right call until traffic grows large enough that the unit economics favor self-hosting.<\/p>\n<h3>Build TURN Into a Platform<\/h3>\n<p>If you&#8217;re building a <a href=\"https:\/\/liveapi.com\/blog\/video-conferencing-api\/\" target=\"_blank\">video conferencing API<\/a> product or any WebRTC-heavy app, you&#8217;ll likely end up running an SFU (Selective Forwarding Unit) anyway. SFUs handle the media forwarding for multi-party calls and partly absorb the TURN function for routes through the SFU. You still need TURN for peer-to-SFU traversal in restricted networks.<\/p>\n<h2>When You Need TURN \u2014 And When You Don&#8217;t<\/h2>\n<p>Not every video app needs TURN. The decision depends on the streaming protocol and topology you&#8217;re using.<\/p>\n<h3>You Need TURN If<\/h3>\n<ul>\n<li>You&#8217;re building a <strong>peer-to-peer WebRTC<\/strong> application: video calls, voice chat, screen sharing, file transfer.<\/li>\n<li>You expect users on <strong>corporate networks, mobile carriers, or restrictive ISPs<\/strong>.<\/li>\n<li>You need <strong>sub-500ms latency<\/strong> and can&#8217;t tolerate the buffering of segmented protocols.<\/li>\n<li>Your app supports <strong>two-way interactive video<\/strong> like telehealth, live tutoring, or interactive live shopping.<\/li>\n<\/ul>\n<h3>You Probably Don&#8217;t Need TURN If<\/h3>\n<ul>\n<li>You&#8217;re doing <strong>one-way broadcast streaming<\/strong> with RTMP or SRT ingest and HLS playback. The encoder pushes to a server, and viewers pull from a CDN \u2014 no peer-to-peer involved.<\/li>\n<li>You&#8217;re streaming <strong>on-demand video<\/strong> from a CDN to an HTML5 player.<\/li>\n<li>Your <strong>latency budget is 3 seconds or higher<\/strong> (most live streaming use cases).<\/li>\n<li>Your media flows through a <strong>central server<\/strong> for transcoding, recording, or distribution.<\/li>\n<\/ul>\n<p>For broadcast-style live streaming \u2014 where one publisher reaches many viewers \u2014 TURN is unnecessary. The encoder pushes <a href=\"https:\/\/liveapi.com\/blog\/what-is-rtmp\/\" target=\"_blank\">RTMP<\/a> or SRT to an ingest endpoint, the server transcodes to HLS, and a <a href=\"https:\/\/liveapi.com\/blog\/cdn-for-video-streaming\/\" target=\"_blank\">CDN for video streaming<\/a> delivers it globally. No NAT traversal needed because viewers initiate outbound HTTP requests that any firewall allows.<\/p>\n<p>If you&#8217;re weighing WebRTC vs broadcast protocols for your use case, our <a href=\"https:\/\/liveapi.com\/blog\/webrtc-vs-hls\/\" target=\"_blank\">WebRTC vs HLS<\/a> and <a href=\"https:\/\/liveapi.com\/blog\/webrtc-vs-rtmp\/\" target=\"_blank\">WebRTC vs RTMP<\/a> comparisons cover the trade-offs in detail.<\/p>\n<h2>TURN Server Security Best Practices<\/h2>\n<p>A poorly configured TURN server is a security liability. Open relays get abused for credential stuffing, DDoS reflection, and traffic laundering. Here&#8217;s how to lock yours down.<\/p>\n<h3>Use Time-Limited Credentials<\/h3>\n<p>Never ship static TURN credentials in client code. Generate short-lived credentials on a backend using the TURN REST API auth scheme \u2014 an HMAC-SHA1 of a timestamp signed with a shared secret. Credentials should expire within minutes.<\/p>\n<h3>Enable TLS<\/h3>\n<p>Always enable port 5349 with a valid TLS certificate (Let&#8217;s Encrypt is free and well-supported). TLS protects credentials in transit and lets TURN punch through firewalls that only allow HTTPS.<\/p>\n<h3>Restrict Permissions<\/h3>\n<p>Coturn&#8217;s <code>no-multicast-peers<\/code> and <code>denied-peer-ip<\/code> settings prevent the relay from forwarding to private RFC 1918 ranges, multicast addresses, or known abuse targets. Block 10.0.0.0\/8, 172.16.0.0\/12, 192.168.0.0\/16, and 127.0.0.0\/8 to prevent the relay from being used as a portal into private networks.<\/p>\n<h3>Rate Limit Allocations<\/h3>\n<p>Use <code>user-quota<\/code> and <code>total-quota<\/code> in Coturn to cap per-user and per-server allocation rates. This blunts the impact of credential theft.<\/p>\n<h3>Monitor Traffic<\/h3>\n<p>Log bandwidth per user and watch for anomalies. A normal video call uses 1\u20133 Mbps. A relay session pushing 100 Mbps is almost certainly being abused.<\/p>\n<h3>Keep Coturn Patched<\/h3>\n<p>Coturn has had CVEs over the years. Subscribe to the GitHub repo notifications and patch promptly.<\/p>\n<h2>TURN Server Performance Considerations<\/h2>\n<p>TURN adds latency and bandwidth cost. How much depends on geography and configuration.<\/p>\n<p><strong>Latency:<\/strong> A TURN relay adds one extra network hop. If the server is geographically close to both peers, the added latency is 20\u201350ms. If it&#8217;s on another continent, it can add 200ms or more. For real-time communication, this matters \u2014 see our guide on <a href=\"https:\/\/liveapi.com\/blog\/what-is-video-latency\/\" target=\"_blank\">video latency<\/a> for a deeper breakdown.<\/p>\n<p><strong>Bandwidth doubling:<\/strong> Every byte sent through TURN is received by the server and re-transmitted. A 2 Mbps video call relayed through TURN costs the server 4 Mbps total (2 in + 2 out). Multiply by your concurrent session count to size capacity.<\/p>\n<p><strong>Geographic distribution:<\/strong> A single TURN server in one region causes high latency for global users. Production deployments use multiple TURN servers worldwide and pick the closest one for each session via DNS-based geolocation or anycast.<\/p>\n<p><strong>CPU:<\/strong> Coturn is lightweight and bottlenecks on bandwidth, not CPU. A modest 4-core VPS can max out a 1 Gbps NIC handling hundreds of concurrent sessions.<\/p>\n<p>For <a href=\"https:\/\/liveapi.com\/blog\/ultra-low-latency-video-streaming\/\" target=\"_blank\">ultra-low-latency video streaming<\/a>, TURN&#8217;s added hop is acceptable for interactive use cases but unnecessary for one-way broadcast where alternatives like Low-Latency HLS (LL-HLS) or CMAF reach sub-3-second latency without relays.<\/p>\n<h2>How LiveAPI Fits Into the Picture<\/h2>\n<p>LiveAPI takes a different architectural approach from WebRTC. Instead of peer-to-peer media, it uses centralized ingest with CDN-distributed playback \u2014 which means no TURN servers, no STUN setup, no ICE candidate gathering.<\/p>\n<p>You publish a stream from any RTMP, SRT, or RTSP encoder to LiveAPI&#8217;s ingest endpoint. The platform transcodes it, generates an HLS manifest, and serves it through Akamai, Cloudflare, and Fastly CDNs to viewers anywhere. Viewers pull the stream over standard HTTPS, which works on every network without firewall traversal concerns.<\/p>\n<p>This trade-off matters for the right use cases:<\/p>\n<ul>\n<li><strong>Broadcast use cases<\/strong> (live events, sports, OTT, church services, conferences) \u2014 LiveAPI handles ingest, transcoding, <a href=\"https:\/\/liveapi.com\/blog\/adaptive-bitrate-streaming\/\" target=\"_blank\">adaptive bitrate streaming<\/a>, and CDN delivery without TURN. Latency is typically 3\u201310 seconds depending on configuration.<\/li>\n<li><strong>Two-way interactive use cases<\/strong> (video calling, screen sharing between two people) \u2014 WebRTC with TURN is the right fit. LiveAPI isn&#8217;t designed for symmetric peer-to-peer.<\/li>\n<li><strong>Live streaming SDK integration<\/strong> \u2014 for mobile and web apps that broadcast to many viewers, our <a href=\"https:\/\/liveapi.com\/blog\/live-streaming-sdk\/\" target=\"_blank\">live streaming SDK<\/a> handles the encoder side, and the playback side works through any HLS player.<\/li>\n<\/ul>\n<p>The pay-as-you-grow pricing model is based on streaming minutes, not relay bandwidth, so the cost structure is predictable as you scale.<\/p>\n<h2>Is a TURN Server Right for Your Project? Quick Checklist<\/h2>\n<p>Answer these questions to decide.<\/p>\n<ol>\n<li><strong>Do you need sub-second latency between two specific users?<\/strong> If yes \u2192 WebRTC + TURN. If no, you have alternatives.<\/li>\n<li><strong>Is the use case symmetric (both sides send video)?<\/strong> If yes \u2192 WebRTC + TURN. If no \u2192 broadcast protocol probably fits better.<\/li>\n<li><strong>Will your users sit behind corporate firewalls or mobile carriers?<\/strong> If yes \u2192 TURN is mandatory for WebRTC.<\/li>\n<li><strong>Are you handling more than 100 concurrent viewers per stream?<\/strong> If yes \u2192 SFU or broadcast architecture, not pure peer-to-peer.<\/li>\n<li><strong>Do you have the ops capacity to run Coturn securely?<\/strong> If no \u2192 use a managed TURN provider.<\/li>\n<\/ol>\n<p>If you answered &#8220;no&#8221; to most of these, you&#8217;re probably looking for a broadcast platform with RTMP\/SRT ingest and HLS output \u2014 not a WebRTC stack with TURN.<\/p>\n<h2>TURN Server FAQ<\/h2>\n<h3>What does a TURN server do?<\/h3>\n<p>A TURN server relays media packets between two devices that can&#8217;t connect directly because of NAT or firewall restrictions. It receives packets from one peer and forwards them to the other, staying in the media path for the entire session.<\/p>\n<h3>Do I really need a TURN server?<\/h3>\n<p>If you&#8217;re building a WebRTC application that needs to work for users on corporate networks, mobile carriers, or strict firewalls, yes. Roughly 20% of WebRTC connections fail without TURN. For one-way broadcast streaming with protocols like RTMP, SRT, or HLS, you don&#8217;t need TURN at all.<\/p>\n<h3>What port does a TURN server use?<\/h3>\n<p>The default port is 3478 for both TCP and UDP. Port 5349 is used for TLS-encrypted TURN. Production deployments often also listen on port 443 to bypass firewalls that block everything except HTTPS.<\/p>\n<h3>What is the difference between a STUN and TURN server?<\/h3>\n<p>STUN only helps a device find its public IP address \u2014 it doesn&#8217;t relay any traffic. Once found, peers connect directly. TURN actively relays every packet between peers when direct connection isn&#8217;t possible. STUN is free to run and lightweight; TURN is bandwidth-intensive and expensive.<\/p>\n<h3>Is there a free TURN server?<\/h3>\n<p>Public free TURN servers exist (like Open Relay Project), but they&#8217;re unreliable for production use because they&#8217;re shared, rate-limited, and have no SLA. You can run your own Coturn instance on a cheap VPS for free, or use a managed provider&#8217;s free tier \u2014 Cloudflare offers 1 TB of relayed bandwidth per month free.<\/p>\n<h3>What is Coturn?<\/h3>\n<p>Coturn is the most widely used open-source TURN and STUN server implementation. It runs on Linux, supports all current TURN features including authentication and TLS, and is what most managed TURN services run under the hood.<\/p>\n<h3>Does TURN use TCP or UDP?<\/h3>\n<p>Both. UDP is preferred for media because it has lower latency. TCP and TLS-over-TCP are fallbacks for networks that block UDP. The TURN client and server negotiate which transport to use, usually via the URL scheme (<code>turn:<\/code> for plain, <code>turns:<\/code> for TLS) and a <code>transport=<\/code> parameter.<\/p>\n<h3>How much does it cost to run a TURN server?<\/h3>\n<p>Self-hosted on a $20\/month VPS handles low-to-moderate traffic. Managed services charge per GB relayed \u2014 Cloudflare at $0.05\/GB (1 TB free), Twilio at $0.40\u2013$0.80\/GB, Metered at $0.40\/GB. A 1-hour 720p video call uses roughly 1\u20132 GB.<\/p>\n<h3>Can a TURN server see my video?<\/h3>\n<p>No. WebRTC media is encrypted end-to-end with DTLS-SRTP. The TURN server forwards encrypted bytes without being able to decode them. It only sees source and destination addresses, packet sizes, and timing.<\/p>\n<h3>What is the latency added by a TURN server?<\/h3>\n<p>A TURN relay adds one network hop. If the server is geographically close (same region as both peers), the added latency is typically 20\u201350ms. Cross-continent relays can add 200ms or more, which is why production deployments use multiple geographic regions.<\/p>\n<h2>Build Live Video Without Managing TURN Servers<\/h2>\n<p>A TURN server is essential infrastructure for WebRTC apps, but it&#8217;s also one more thing to deploy, secure, and scale. If your use case is broadcast streaming rather than peer-to-peer calling, you can skip TURN entirely by using RTMP\/SRT ingest and HLS playback.<\/p>\n<p>LiveAPI gives you that architecture out of the box \u2014 RTMP, SRT, and RTSP ingest, <a href=\"https:\/\/liveapi.com\/blog\/adaptive-bit-rate\/\" target=\"_blank\">adaptive bitrate streaming<\/a>, multi-CDN delivery, and an embeddable player \u2014 without TURN servers, signaling infrastructure, or NAT traversal to manage. <a href=\"https:\/\/liveapi.com\/\" target=\"_blank\">Try LiveAPI free<\/a> and ship a live streaming feature in days instead of months.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">12<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span> Roughly 20% of WebRTC sessions can&#8217;t connect peer-to-peer because of strict NAT, corporate firewalls, or symmetric NAT mappings. When that happens, the call drops \u2014 unless you route the media through a TURN server. A TURN server is the safety net that keeps real-time video, audio, and data flowing when a direct connection between two [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_yoast_wpseo_title":"What Is a TURN Server? How It Works, Setup, and Use Cases %%sep%% %%sitename%%","_yoast_wpseo_metadesc":"Learn what a TURN server is, how it works with STUN and ICE, ports it uses, setup with Coturn, costs, and when WebRTC apps need one.","inline_featured_image":false,"footnotes":""},"categories":[31],"tags":[],"class_list":["post-1065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-webrtc"],"jetpack_featured_media_url":"https:\/\/liveapi.com\/blog\/wp-content\/uploads\/2026\/05\/turn-server.jpg","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.6.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"description\" content=\"Learn what a TURN server is, how it works with STUN and ICE, ports it uses, setup with Coturn, costs, and when WebRTC apps need one.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/liveapi.com\/blog\/turn-server\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What Is a TURN Server? How It Works, Setup, and Use Cases - LiveAPI Blog\" \/>\n<meta property=\"og:description\" content=\"Learn what a TURN server is, how it works with STUN and ICE, ports it uses, setup with Coturn, costs, and when WebRTC apps need one.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/liveapi.com\/blog\/turn-server\/\" \/>\n<meta property=\"og:site_name\" content=\"LiveAPI Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-22T02:46:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-22T02:46:25+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"18 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/liveapi.com\/blog\/#website\",\"url\":\"https:\/\/liveapi.com\/blog\/\",\"name\":\"LiveAPI Blog\",\"description\":\"Live Video Streaming API Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/liveapi.com\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/liveapi.com\/blog\/turn-server\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/liveapi.com\/blog\/wp-content\/uploads\/2026\/05\/turn-server.jpg\",\"width\":1880,\"height\":1162,\"caption\":\"Photo by Sergei Starostin on Pexels\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/liveapi.com\/blog\/turn-server\/#webpage\",\"url\":\"https:\/\/liveapi.com\/blog\/turn-server\/\",\"name\":\"What Is a TURN Server? How It Works, Setup, and Use Cases - LiveAPI Blog\",\"isPartOf\":{\"@id\":\"https:\/\/liveapi.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/liveapi.com\/blog\/turn-server\/#primaryimage\"},\"datePublished\":\"2026-05-22T02:46:08+00:00\",\"dateModified\":\"2026-05-22T02:46:25+00:00\",\"author\":{\"@id\":\"https:\/\/liveapi.com\/blog\/#\/schema\/person\/98f2ee8b3a0bd93351c0d9e8ce490e4a\"},\"description\":\"Learn what a TURN server is, how it works with STUN and ICE, ports it uses, setup with Coturn, costs, and when WebRTC apps need one.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/liveapi.com\/blog\/turn-server\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/liveapi.com\/blog\/#\/schema\/person\/98f2ee8b3a0bd93351c0d9e8ce490e4a\",\"name\":\"govz\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/liveapi.com\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ab5cbe0543c0a44dc944c720159323bd001fc39a8ba5b1f137cd22e7578e84c9?s=96&d=mm&r=g\",\"caption\":\"govz\"},\"sameAs\":[\"https:\/\/liveapi.com\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/comments?post=1065"}],"version-history":[{"count":1,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1065\/revisions"}],"predecessor-version":[{"id":1067,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1065\/revisions\/1067"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/media\/1066"}],"wp:attachment":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/media?parent=1065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/categories?post=1065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/tags?post=1065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}