How to Set Up and Configure a VPS for WebRTC Media Server Applications

WebRTC (Web Real-Time Communication) powers modern browser-based video conferencing, live streaming, and peer-to-peer data channels. Unlike traditional streaming protocols that require plugins or native applications, WebRTC works directly in the browser, making it the backbone of platforms like Google Meet, Discord, and Jitsi. Deploying a WebRTC media server on a VPS requires careful network configuration, TURN server setup, and kernel tuning to handle real-time media traffic at scale. This guide walks through provisioning a Linux VPS for production WebRTC workloads using technologies like coturn, mediasoup, and Janus.

Understanding WebRTC Server Architecture

A WebRTC deployment on a VPS typically consists of three components:

  • Signaling server — Handles connection negotiation (WebSocket-based, lightweight)
  • Media server — Processes, transcodes, and routes audio/video streams (SFU or MCU architecture)
  • TURN server — Relays media when NAT traversal fails (coturn is the standard)

For most deployments, an SFU (Selective Forwarding Unit) architecture is preferred over MCU (Multipoint Control Unit) because it minimizes CPU usage by forwarding streams without mixing them. Popular open-source SFU options include mediasoup, Janus, and LiveKit.

When selecting a VPS provider for WebRTC, prioritize those with low-latency network paths and generous bandwidth limits. You can compare VPS providers on our comparison table to find plans with unmetered bandwidth and multiple PoP locations for optimal media routing.

Prerequisites

  • Ubuntu 24.04 LTS VPS with at least 4 GB RAM and 2 vCPUs
  • A domain name with DNS A records pointing to your VPS IP
  • Ports 80, 443, 3478 (UDP/TCP), 5349 (TCP), and 49152-65535 (UDP) open in firewall
  • Node.js 20+ or Go for signaling server
  • Docker and Docker Compose (optional, for containerized deployment)

Step 1: Kernel and Network Tuning for Real-Time Media

WebRTC is sensitive to jitter and packet loss. Edit /etc/sysctl.conf with these optimizations:

# /etc/sysctl.d/99-webrtc.conf

# Increase UDP buffer sizes for media traffic
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216

# TCP BBR congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Connection tracking limits
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_tcp_timeout_established = 432000

# Enable IP forwarding for TURN
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Apply with sysctl -p /etc/sysctl.d/99-webrtc.conf. Enable BBR congestion control for significantly better throughput on lossy connections.

Step 2: Deploy coturn TURN Server

The TURN server is critical — without it, users behind symmetric NATs or corporate firewalls cannot establish peer connections. Install coturn:

sudo apt update && sudo apt install -y coturn

Configure /etc/turnserver.conf:

listening-port=3478
tls-listening-port=5349
listening-ip=0.0.0.0
relay-ip=YOUR_VPS_IP
fingerprint
lt-cred-mech
user=webrtc:strong_password_here
realm=yourdomain.com
# TLS certificate paths (use certbot or Let's Encrypt)
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem
# Expose STUN endpoint for NAT detection
external-ip=YOUR_VPS_IP
min-port=49152
max-port=65535

Enable and start coturn:

sudo systemctl enable coturn && sudo systemctl start coturn

Verify with a STUN test: sudo journalctl -u coturn | grep STUN — you should see binding request responses.

Step 3: Deploy mediasoup SFU Media Server

Mediasoup is a high-performance WebRTC SFU written in C++ with Node.js bindings. Create a project directory and initialize:

mkdir /opt/mediasoup-server && cd /opt/mediasoup-server
npm init -y
npm install mediasoup@3 express socket.io

Create server.js with minimal SFU configuration:

const mediasoup = require('mediasoup');
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

async function startMediasoup() {
  const worker = await mediasoup.createWorker({
    logLevel: 'warn',
    logTags: ['info', 'ice', 'dtls', 'rtp', 'srtp', 'rtcp', 'score'],
  });

  const router = await worker.createRouter({
    mediaCodecs: [
      { kind: 'audio', mimeType: 'audio/opus', clockRate: 48000, channels: 2 },
      { kind: 'video', mimeType: 'video/VP9', clockRate: 90000 },
      { kind: 'video', mimeType: 'video/H264', clockRate: 90000, parameters: { 'level-asymmetry-allowed': 1 } },
    ],
  });

  console.log('Mediasoup router created. Listening on port 3000');
  return { worker, router };
}

startMediasoup();
server.listen(3000);

Step 4: Firewall Configuration

sudo ufw allow 80/tcp    # HTTP (for HTTPS redirect)
sudo ufw allow 443/tcp   # HTTPS
sudo ufw allow 3478/tcp  # TURN TCP
sudo ufw allow 3478/udp  # TURN UDP
sudo ufw allow 5349/tcp  # TURN TLS
sudo ufw allow 49152:65535/udp  # Media ports
sudo ufw enable

Performance Benchmarks and Scaling

VPS SpecsMax Concurrent SFU Streams (720p)TURN Relay BandwidthRecommended Use Case
2 vCPU / 4 GB RAM50-80~500 MbpsSmall team / internal use
4 vCPU / 8 GB RAM150-250~1 GbpsProduction webinars
8 vCPU / 16 GB RAM400-600~2 GbpsMulti-room conferencing

These estimates assume NVMe storage, dedicated CPU cores, and a 1 Gbps network interface. Actual throughput depends on codec choice (VP9 uses ~30% more CPU than H.264) and whether transcoding is enabled.

Conclusion

Deploying a WebRTC media server on a VPS requires more than just installing packages — kernel tuning for real-time traffic, proper TURN relay configuration, and careful port management are essential for production quality. Start with a single mediasoup worker on a 4 vCPU VPS and scale horizontally by adding more workers behind a load balancer as your user base grows. Before committing to a provider, see performance benchmarks on our comparison page to identify VPS plans with the network throughput and CPU guarantees that real-time media demands.

Leave a Reply