What matters most when validating a TURN relay for live video
- Function comes first: I want to see a real `relay` candidate, not just host or server-reflexive candidates.
- Realistic conditions matter: the test should mirror the actual codec, bitrate, browser, and network path used in production.
- Performance is about headroom: a relay that works for one call can still fail when concurrency, bandwidth, or file descriptors climb.
- UDP is the baseline: TCP fallback may rescue connectivity, but it often hides the latency profile you care about for live video.
- Diagnostics should agree: browser logs, server logs, and load behaviour need to tell the same story.
What a good relay test should prove
A proper relay test is not just a yes-or-no check. I want to know three things: first, that the server can allocate and authenticate sessions; second, that the client can actually move media through the relay; and third, that the path stays stable long enough to matter for a live broadcast or interactive stream. If any one of those fails, the server is not ready for production, even if the basic connection screen looks fine.
| Connection type | What it tells me | Why it matters |
|---|---|---|
| Host | The client is talking on its local network path | Useful for direct calls, but not proof that the fallback path works |
| Srflx | STUN found a public-facing address | Shows NAT traversal is possible without relaying media |
| Relay | The TURN server is carrying the traffic | This is the result that matters when direct peer-to-peer fails |
In practice, I treat `relay` as the real success signal. If the session only reaches host or srflx candidates, the relay is not part of the media path, which means the fallback scenario has not been proven yet. Once that distinction is clear, the next step is to make the test environment look like the one your viewers will actually use.

Set up a realistic test path before you measure anything
The fastest way to get false confidence is to test with the wrong shape of traffic. If your production stream is 1080p at 4 to 6 Mbps, do not validate the relay with a tiny demo clip and expect meaningful results. I always mirror the real application as closely as I can: same browser, same codec, same frame rate, same authentication model, and the same network type the audience is likely to face.
Match the production stream profile
For live video, bitrate and packet cadence matter more than people think. A 2 Mbps stream behaves very differently from a 6 Mbps stream once retransmissions, encryption, and relay overhead are added. If your platform uses adaptive bitrate ladders, I test at the top two rungs, not just the lowest one, because that is where a relay tends to show strain first.Include unfriendly networks
I always include at least one restrictive path in the matrix: office Wi-Fi, hotel Wi-Fi, home broadband behind a carrier-grade NAT, and a mobile hotspot. If your audience is in the UK, it is especially useful to compare fixed fibre and mobile networks, because the NAT behaviour and firewall rules can differ enough to change the result completely. A relay that only works on the same LAN as the server has not really been tested.
Keep the credentials and ports honest
Do not simplify the configuration just to make the first test pass. Use the same realm, the same username and secret flow, and the same relay port range you intend to ship. That is where many deployment mistakes hide, especially when teams forget that media ports need to be open end-to-end, not just the control port.
When the setup matches reality, the browser tools become much easier to read, because you are no longer debugging a toy environment. That leads naturally to the next question: how do you confirm, from the client side, that the relay is really doing the work?
Use browser diagnostics to confirm that traffic really relays
My first pass is always the browser, because it shows what the client believes is happening. The WebRTC Trickle ICE sample is useful here because it makes candidate gathering visible and tells you directly whether a TURN server produced a `relay` candidate. That is the cleanest functional check before you move on to heavier testing.
| Tool | What I look for | Passing sign |
|---|---|---|
| Trickle ICE sample | Candidate type and authentication behaviour | A `relay` candidate appears and gathering completes normally |
| Browser internals | Selected candidate pair, ICE state, and restarts | The nominated pair stays stable instead of thrashing |
| Server logs | Allocations, refreshes, and authentication errors | Allocations increase normally and timeouts stay low |
When I inspect the client, I want to see more than a connection icon turning green. I want to see a nominated relay pair, steady refresh behaviour, and no repeated credential errors. In Chrome, I also make sure the test is not artificially limited by permissions, because missing media permissions can reduce candidate visibility in a way that confuses the picture. Once the browser confirms the relay path, the real work begins: load.
Measure performance under load, not just connection success
A TURN relay is not a passive witness. It forwards every byte, so the server sees both directions of the stream, and the bandwidth bill rises quickly. As a rough mental model, a 4 Mbps media flow can translate into around 8 Mbps of relay traffic before overhead, and once you multiply that by 20 sessions, you are already near 160 Mbps of server traffic. That is why a relay can look fine in a single-call test and still fail in production.
Read Also: TCP in Live Video - Where It Helps & Where It Hurts Your Stream
Watch the metrics that actually move
| Metric | What healthy looks like | What usually means trouble |
|---|---|---|
| Bandwidth | Rises smoothly as sessions increase | A sudden plateau, drop, or uneven spikes |
| CPU | Load is spread across cores without one thread pegging out | One core sits high while traffic keeps growing |
| Latency and jitter | RTT stays predictable across a soak test | Delay creeps up or starts to swing between samples |
| File descriptors and ports | Well below the system limit | Allocation failures or “too many open files” behaviour |
| Session longevity | Calls survive long enough to refresh cleanly | Sessions die after a few minutes or during NAT churn |
As a working threshold, I start paying attention when round-trip time moves past roughly 150 ms for interactive video, and I treat 250 ms as a serious warning sign. I also like to run two phases of stress: a 30-minute soak at expected peak and then a shorter burst at 125 to 150 percent of that level. The soak exposes leaks and slow degradation; the burst exposes the ugly edge cases. Once you have that data, you can separate genuine capacity from wishful thinking.
Common failure modes that make a relay look healthier than it is
The most misleading test result is the one that passes for the wrong reason. I see the same traps over and over: a relay that only works on the same LAN, a deployment that silently falls back to TCP, or a network path that never exercises the port range where the real traffic will live. Those problems are easy to miss if you only check whether the page loads once.
- Testing inside the same network: office-to-office or device-to-server tests can hide NAT behaviour that appears immediately for remote viewers.
- TCP fallback masking UDP problems: TCP may keep the session alive, but for live video it often gives you more latency and less predictable jitter.
- Wrong public address or relay mapping: the server may be reachable, but clients still cannot use the advertised address correctly.
- Port range not open end-to-end: the control port answers, but the relay ports are blocked, so media dies later in the negotiation.
- Authentication drift: changing secrets, realms, or time settings can produce intermittent failures that look like random network noise.
- Load balancer assumptions: some deployments need related TURN sessions to stay mapped to the same backend, otherwise the relay state breaks.
My rule is simple: if the session only works on TCP, I do not call that a clean result for live video unless the audience genuinely lives behind severe restrictions. UDP remains the baseline I care about, and TCP is the exception path. Once those traps are removed, the remaining question is what to do with the numbers you collected.
The decisions I make before calling a TURN deployment ready
At the end of the test cycle, I want to make operational decisions, not just technical observations. If the relay is close to the edge at expected peak, I add headroom before launch. If the server shows auth failures, I fix the credential flow before I scale. If the relay only looks good when traffic stays low, I treat that as a capacity warning rather than a success.
- Keep headroom: I like at least 30 to 50 percent spare capacity above the heaviest observed relay load.
- Alert on the right signals: authentication failures, allocation timeouts, port exhaustion, and sustained CPU pressure deserve alerts, not just total uptime.
- Retest after changes: firewall rules, certificates, browser updates, codec changes, and network moves can all change relay behaviour.
- Place relays near the audience: for UK-focused live video, I would rather keep relay traffic close to the main viewer base than force it through an unnecessary long-haul path.
- Treat scale-out carefully: if you add more relays, make sure the routing model still preserves the session behaviour your deployment depends on.
When a relay only proves itself in the lab, I do not trust it. I want one clean relay candidate, one realistic streaming path, and one load test that goes beyond expected peak. When those three line up, the TURN layer becomes boring in the best possible way, and that is exactly what I want before I put a live video workflow in front of real viewers.