Real-Time and WebRTC
Most platforms make WebRTC a research project: provision a TURN server, manage UDP port pools, wire up STUN, generate ICE credentials, hope your STUN/TURN survives a load test. On Watasu it’s a process suffix.
Name a process *-rtc and Watasu provisions a dedicated TURN gateway per process, allocates a public UDP port, gives every replica a stable public hostname, and injects TURN_* env vars into your container.
That’s the whole setup.
When to use *-rtc
Section titled “When to use *-rtc”- WebRTC SFUs (Selective Forwarding Units) for video conferencing
- voice agents and call-handling backends
- real-time gaming or low-latency multiplayer
- live streaming ingest with WebRTC publish
- anything where UDP, low latency, and ICE matter
A minimal example
Section titled “A minimal example”web: bundle exec puma # signaling serversfu-rtc: node sfu/server.js # the SFUworker: bundle exec sidekiqPush, scale, done.
git push watasu mainwatasu pods:scale sfu-rtc=2 --app my-appWhat Watasu provisions for each *-rtc process
Section titled “What Watasu provisions for each *-rtc process”For every process whose name ends in -rtc, Watasu creates:
- a dedicated TURN gateway
- a per-process public TURN hostname of the form
<route-token>.turn.watasuhost.com - a per-replica public hostname for direct-replica routing:
<route-token>-01.watasuhost.com,<route-token>-02.watasuhost.com, and so on - a unique public UDP port allocated from a managed pool
- the matching TURN credentials as env vars in the container
When you scale the process, every new replica gets its own stable hostname.
Environment variables
Section titled “Environment variables”Each *-rtc container receives:
| Variable | Purpose |
|---|---|
TURN_SHARED_SECRET | Used to mint ephemeral TURN credentials at request time |
TURN_HOSTNAME | Public TURN hostname for this process |
TURN_PORT | Public UDP port allocated to this process |
TURN_REALM | TURN realm used by your gateway |
WATASU_RTC_* | Generic platform-side info (process name, replica index) |
Use TURN_SHARED_SECRET to generate ephemeral credentials per session in your signaling layer (the standard ephemeral-credential pattern). Hand the resulting credentials to the browser as the ICE configuration.
Bring your own SFU
Section titled “Bring your own SFU”Watasu provides the ICE/TURN infrastructure. The SFU itself is your code or a library you choose:
- mediasoup (Node.js) — popular, programmable
- Pion (Go) — pure-Go WebRTC stack
- Janus, Jitsi Videobridge, LiveKit Server — drop-in SFU servers
- anything else that speaks WebRTC
Build it into a container, name the process *-rtc, and it works.
Scaling RTC processes
Section titled “Scaling RTC processes”*-rtc processes scale just like any other:
watasu pods --app my-appwatasu pods:scale sfu-rtc=4 --app my-appwatasu pods:type sfu-rtc=standard-4x --app my-appEach replica gets its own public hostname (<route-token>-01..., -02..., etc.). Use these hostnames in your signaling layer to route a session to a specific replica when you need replica affinity.
Region constraints
Section titled “Region constraints”*-rtc workloads run in nbg1 or fsn1 (the two German data centers) for low-latency UDP routing. You don’t pick — Watasu handles placement.
Why per-process TURN matters
Section titled “Why per-process TURN matters”A shared TURN server is a shared bottleneck. Once one tenant’s call volume saturates the cluster’s TURN bandwidth, everyone suffers. Watasu provisions a dedicated TURN gateway per *-rtc process so:
- your traffic doesn’t compete with another tenant’s
- your failure domain is your own
- scaling your RTC process scales your TURN capacity at the same time
This is the difference between a hosting setup that survives a viral product launch and one that doesn’t.
What this doesn’t do
Section titled “What this doesn’t do”- It doesn’t ship an SFU for you. You bring the WebRTC code.
- It doesn’t handle signaling — that’s a regular
webprocess in your app. - It doesn’t replace authentication or session management — that’s your app’s job.
For private service-to-service TCP (microservices, not WebRTC), see Private Networking.