WebRTC Video Calls: ICE, TURN, and SFU Setup

Why WebRTC Calls Require a Comprehensive Approach?

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1026
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

Why WebRTC Calls Require a Comprehensive Approach?

WebRTC provides a powerful API for video calls, but a production-ready solution requires more than a single RTCPeerConnection. Direct P2P connection often breaks due to symmetric NAT: up to 15–20% of sessions cannot establish a direct channel. Corporate firewalls blocking UDP add another 10–15% of failures. Without the proper stack (ICE, TURN, signaling server, SFU), calls either fail or deliver unstable quality. We solve these problems: we configure each component for your specific infrastructure so that video calls work stably in any network—from home Wi-Fi to corporate VPNs.

RTCPeerConnection manages ICE candidates, media streams, and DTLS-SRTP encryption. But WebRTC itself does not include SDP offer exchange—a signaling server is required. A typical production stack:

Component Options
Signaling server Socket.IO, WebSocket (Go/Node), Phoenix Channels
ICE/STUN coturn, Twilio STUN, Google STUN
TURN server coturn on a dedicated VPS, Twilio TURN, Xirsys
Media server (SFU) mediasoup, Janus, LiveKit, Jitsi Videobridge
Client library native RTCPeerConnection or simple-peer, mediasoup-client

Without proper configuration of each component, calls will work only locally or fail behind NAT. We integrate WebRTC turnkey, guaranteeing stability.

How a TURN Server Solves the NAT Problem?

A STUN server determines the external IP, but with symmetric NAT it is useless. A TURN server relays media traffic when P2P is impossible. We deploy coturn with TLS on port 443. This increases traversal through corporate proxies by 3 times compared to UDP TURN. Configuration:

coturn deployment with TLS
# /etc/turnserver.conf listening-port=3478 tls-listening-port=5349 realm=your-domain.com server-name=your-domain.com lt-cred-mech use-auth-secret static-auth-secret=YOUR_SECRET total-quota=100 bps-capacity=0 stale-nonce=600 cert=/etc/letsencrypt/live/your-domain.com/fullchain.pem pkey=/etc/letsencrypt/live/your-domain.com/privkey.pem 

For high loads (100+ concurrent calls), we use coturn clustering with DNS round-robin. Each instance holds up to 100 sessions.

What is an SFU and When is It Needed?

SFU (Selective Forwarding Unit) is a media server that forwards streams without mixing. Unlike mesh topology (P2P), where 5 participants create 10 connections per client, an SFU receives one stream and relays it to recipients. Client load is reduced by 9 times with 10 participants. We use mediasoup or LiveKit depending on performance and flexibility requirements.

Parameter P2P (mesh) SFU
Max participants 4-6 50+
Client requirements High (n-1 connections) Low (1 connection)
Server load Zero Medium
Complexity Low Medium
Call recording Client-only Server-side

SFU allows serving 10 times more participants with the same bandwidth.

Signaling Server: Implementation on Node.js + Socket.IO

The signaling server relays SDP offers, answers, and ICE candidates between participants. Example server-side code:

// server.js io.on('connection', (socket) => { socket.on('join-room', (roomId, userId) => { socket.join(roomId); socket.to(roomId).emit('user-connected', userId); socket.on('offer', (offer, targetId) => { io.to(targetId).emit('offer', offer, socket.id); }); socket.on('answer', (answer, targetId) => { io.to(targetId).emit('answer', answer, socket.id); }); socket.on('ice-candidate', (candidate, targetId) => { io.to(targetId).emit('ice-candidate', candidate, socket.id); }); socket.on('disconnect', () => { socket.to(roomId).emit('user-disconnected', userId); }); }); }); 

This code is the basis for P2P and SFU calls. A TURN server costs about $10–20 per month for a small project, and traffic savings from Simulcast reach 50%.

Client Side: RTCPeerConnection and Media Management

On the client, we create an RTCPeerConnection with ICE/TURN servers and obtain a media stream:

const pc = new RTCPeerConnection({ iceServers: [ { urls: 'stun:stun.your-domain.com:3478' }, { urls: 'turn:turn.your-domain.com:3478', username: generateTurnUsername(ttl), credential: generateTurnCredential(username, secret), }, ], iceTransportPolicy: 'all', }); const stream = await navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 1280 }, height: { ideal: 720 }, frameRate: { ideal: 30 } }, audio: { echoCancellation: true, noiseSuppression: true, sampleRate: 48000 }, }); stream.getTracks().forEach(track => pc.addTrack(track, stream)); 

To improve quality, we use Simulcast with SFU—the client sends three streams of different resolutions:

pc.addTransceiver(videoTrack, { direction: 'sendonly', sendEncodings: [ { rid: 'low', maxBitrate: 150000, scaleResolutionDownBy: 4 }, { rid: 'mid', maxBitrate: 500000, scaleResolutionDownBy: 2 }, { rid: 'high', maxBitrate: 1500000 }, ], }); 

The SFU selects the appropriate layer for each receiver, delivering the best quality under limited bandwidth. Additionally, we monitor connection state through oniceconnectionstatechange and onconnectionstatechange handlers, implementing automatic reconnection during temporary failures.

Monitoring and Optimization

After launch, it is crucial to track real call metrics. We use getStats() to collect key indicators:

  • packetsLost – packet loss percentage; if exceeds 5%, we initiate adaptive bitrate reduction.
  • jitter – jitter; if >30ms, we switch audio codec to Opus with lower latency.
  • roundTripTime – RTT; high RTT signals a need to change TURN server or route.

Note: as stated in the WebRTC API documentation, this data helps quickly identify problematic sessions and adjust configuration.

What's Included: Deliverables

After implementation, you receive:

  • architectural documentation with topology, servers, and flows;
  • source code of the signaling server and client integration (Git repository);
  • access to the TURN server (time-limited credentials);
  • team training (2-hour session on operation);
  • one month of post-release support (monitoring via getStats(), incident resolution).

Implementation Process and Timelines

WebRTC implementation proceeds in five stages:

  1. Analysis – audit of current infrastructure, use cases, expected load.
  2. Design – selection of topology (P2P or SFU), servers, codecs.
  3. Implementation – configuration of TURN/STUN, signaling server, client integration.
  4. Testing – load testing, different networks, mobile devices.
  5. Deployment – go-live, monitoring via getStats().

Timelines:

  • P2P video call with signaling server – 3 to 5 days.
  • Group calls via SFU – 2 to 3 weeks.
  • Recording and post-processing – plus 1 week.
  • Full conferencing platform – 6 to 10 weeks.

Pricing is determined after the audit. Contact us for a free consultation—we will evaluate your project and propose the optimal architecture. Order WebRTC implementation and get stable video calls in any network.