coturn
Open-source TURN and STUN server for WebRTC
coturn is a widely used, free TURN and STUN server implementation that enables WebRTC media to traverse NAT and firewalls. It is a common companion to self-hosted video conferencing tools.
Key features
- Standards-compliant TURN/STUN
- Essential for WebRTC NAT traversal
- High performance
- Supports TLS and DTLS
Pros & cons
Strengths
- Battle-tested and widely used
- Standards compliant
- Low overhead
Trade-offs
- Infrastructure component, not user-facing
- Configuration can be tricky
Last reviewed Sep 13, 2026 · 861 words
If a self-hosted video call works at home and fails from a hotel, a corporate office or a phone on carrier NAT, the missing piece is coturn. WebRTC tries to connect the two participants directly; when both sit behind restrictive NAT, the direct path never forms and the call rings, connects, and shows a frozen black tile. A TURN server is a relay with a public IP that both sides can reach, and coturn is the implementation nearly everyone uses, from Nextcloud Talk to Matrix to Jitsi. Users never see it. It is the thing that makes the calls from the worst networks succeed instead of failing silently.
It needs a public IP, or it is decorative
The relay must be reachable by both parties on a routable address. Behind CGNAT it cannot work at all. Behind an ordinary home router with port forwarding it works if you set external-ip= to the public address, because coturn has to put that address into the candidates it hands out. The cleanest home is a small VPS with a real IPv4, since the relay also carries all the media of every relayed call, and a VPS has the upload bandwidth a home line does not. A 64 MB footprint means the smallest instance you can rent is plenty for the process; the constraint is the network, not the RAM.
Twelve config lines do 90 percent of the work
/etc/turnserver.conf has around 200 options and most installs need these:
listening-port=3478
tls-listening-port=5349
realm=turn.example.com
use-auth-secret
static-auth-secret=a-long-random-hex-string
external-ip=203.0.113.10
min-port=49152
max-port=65535
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
fingerprint
no-cli
use-auth-secret with a shared secret is the mode every modern app wants: the app mints short-lived credentials from the secret, so no per-user TURN accounts exist. realm is required and can be any string, though the hostname is conventional. The port range is where relayed media flows and it must be open in every firewall between the server and the internet; 3478 needs TCP and UDP, 5349 needs TCP for TURN over TLS, the transport that gets through the strictest corporate networks. Test on the Trickle ICE sample page: enter the server and a credential derived from the secret, gather candidates, and look for one of type relay. No relay candidate means the firewall or external-ip is wrong, and nothing else is worth debugging until it appears.
Docker works, but only with host networking
The official coturn/coturn image runs fine, with one non-negotiable: network_mode: host. Publishing a 16,000-port range through Docker's port mapping takes minutes to start and burns memory on the proxy processes; host networking removes the problem and is what the project recommends. Mount the config and certificates read-only, and restart coturn after each certificate renewal, because assuming it reloads them on its own is how a TURN server ends up serving an expired certificate for two months without anyone noticing.
Bandwidth is the real cost
Every relayed call sends each participant's audio and video through the server in both directions. A two-person 720p call is roughly 1 to 2 Mbit/s each way per participant; a relayed three-way call pushes several megabits sustained. On a VPS with a transfer cap, a family that calls daily can burn 100 GB a month; on an unmetered port it is nothing. Set total-quota and bps-capacity if you want a ceiling, and turn on verbose only while debugging, because coturn logs are chatty enough to fill a small disk.
Wiring it into the apps that need it
Nextcloud Talk has a TURN server field under Talk settings that takes host, port and the shared secret, plus a test button that confirms the relay. Synapse takes turn_uris, turn_shared_secret and turn_user_lifetime in homeserver.yaml, and Element clients pick the credentials up automatically. Jitsi Meet usually needs no coturn, because its videobridge is itself a public relay, though the Docker distribution can use one for the TLS fallback. LiveKit ships an embedded TURN and does not need this either. One coturn serves all of them at once from the same secret, which is the normal arrangement across the video conferencing category: one relay shared by everything.
What I'd do
coturn on a VPS costing about 5 dollars a month with a public IPv4, host networking, use-auth-secret, TLS on 5349 from the same Let's Encrypt certificate as the domain, the port range open in the provider's firewall, and a relay candidate confirmed on the Trickle ICE page before touching any app. Then the same secret into Nextcloud Talk and Synapse. It is 30 minutes of work that turns "calls sometimes fail" into "calls work", and nobody who benefits will ever know it exists, which is the correct outcome for infrastructure.
Similar video conferencing apps
Jitsi Meet
Video ConferencingSecure, fully featured video conferencing
Replaces Zoom, Google Meet
LiveKit
Video ConferencingScalable WebRTC infrastructure for real-time audio and video
Replaces Twilio, Agora
BigBlueButton
Video ConferencingVirtual classroom and web conferencing for education
Replaces Zoom, Microsoft Teams
Janus
Video ConferencingGeneral-purpose, lightweight, minimalist WebRTC Server
mediasoup
Video ConferencingCutting-edge WebRTC SFU library for Node.js
Replaces Twilio Video
MiroTalk SFU
Video ConferencingScalable WebRTC video conferencing with an SFU, up to 4K