IQAAI Media Fabric: Breaking FreeSWITCH Server Affinity for WebRTC at Scale
Every large WebRTC deployment eventually runs into the same wall: FreeSWITCH server affinity. A browser, a softphone, or a live agent negotiates media with exactly one FreeSWITCH box, and from that moment on, it is pinned there. That single pin is quietly responsible for a surprising share of the scaling headaches, failover gaps, and regional silos that contact-center and communications platforms fight every day.
We built IQAAI Media Fabric to remove that pin entirely. With Media Fabric and its FreeSWITCH endpoint module, mod_fabric, any FreeSWITCH instance, in any availability zone, can serve media for any WebRTC endpoint with no affinity, no per-server lock-in, and no regional islands.
This post explains what server affinity actually costs you, how Media Fabric eliminates it, and why the architecture underneath, a clean split between a signaling control plane and a direct media plane, is what makes affinity-free routing, zone-level resilience, and near-linear horizontal scale possible at the same time.

What is FreeSWITCH server affinity, and why it hurts
In a traditional FreeSWITCH + WebRTC stack using Verto or SIP over WebSockets, the media session is anchored to the specific server that terminated it. The DTLS-SRTP keys, the ICE candidates, and the RTP flow all belong to that one instance. That is server affinity, and it creates four compounding problems:
- Scaling is vertical, not horizontal. Because an endpoint can only talk to its server, you scale a hot instance up rather than spreading load out. Capacity planning becomes a game of oversizing every box for peak.
- Failover is disruptive. If the pinned server degrades or dies, the calls it was holding go with it. There is no other instance that can transparently pick up those media sessions.
- Geography gets rigid. Endpoints are effectively bound to a region. Serving users in another part of the world means standing up regional silos and routing users to their cluster.
- Operations are brittle. Rolling upgrades, autoscaling, and zone maintenance all have to work around the fact that live media cannot be moved.
For a cloud contact center (CCaaS) or communications platform (CPaaS), those constraints translate directly into cost, downtime risk, and a ceiling on how far you can distribute your infrastructure. Server affinity is the invisible tax on every FreeSWITCH-based real-time platform.
Introducing IQAAI Media Fabric
IQAAI Media Fabric is a control plane for a pool of affinity-free FreeSWITCH nodes and homeless agents.
Here is the core idea. Instead of registering an agent browser to a particular FreeSWITCH server, each endpoint holds one durable WebSocket to the Fabric and is never registered on any FreeSWITCH node at all. When a node needs to reach that agent, to ring them, bridge a call, or send DTMF, it signals the Fabric, and the Fabric translates that into standard Verto signaling over the agent WebSocket.
Crucially, the Fabric never touches the media. It brokers the signaling and gets out of the way. The actual audio and video, DTLS-SRTP over ICE, flow directly between the FreeSWITCH node and the browser. That single design decision is what unlocks everything else.
The result, in the words of our product tagline: mod_fabric removes FreeSWITCH affinity, so any server, in any AZ, reaches any WebRTC endpoint.
How IQAAI Media Fabric works
Media Fabric cleanly separates two concerns that traditional FreeSWITCH deployments fuse together: signaling (who is calling whom, ring, answer, hold, transfer) and media (the actual RTP audio/video). Splitting them is what makes affinity optional.
gRPC bidi stream Verto / WebSocket
FreeSWITCH node <-----------------------> Fabric <--------------------> WebRTC endpoint
(mod_fabric) (browser / app)
\ /
\______________________ DTLS-SRTP / ICE media (direct) _______________/
the Fabric is NEVER in the media path
The control plane: gRPC on one side, Verto on the other
- Node to Fabric is a single long-lived gRPC bidirectional stream. Each FreeSWITCH node opens one stream to the Fabric and multiplexes all of its calls over it, keyed by call ID. The node is the client; the Fabric is the server.
- Fabric to endpoint is Verto JSON-RPC over a WebSocket, the same protocol FreeSWITCH
mod_vertospeaks, so standard WebRTC clients work unchanged. The Fabric is the Verto server.
The Fabric shuttles SDP offers and answers between these two worlds. Once the endpoints have each other media parameters, they connect directly.
The media plane: direct, encrypted, and never proxied
Because media flows straight from the FreeSWITCH node to the browser over DTLS-SRTP, the Fabric carries zero RTP. This is the detail that makes the whole system practical:
- The Fabric does not need to be near the media. It is a lightweight signaling broker, so it can be small, stateless-ish, and horizontally scaled without moving gigabytes of audio.
- Any node can serve any endpoint. Since the pin was really about media termination, and media is now negotiated per call rather than tied to a registration, a fresh call can be handed to whichever node is best right now.
- Media survives signaling blips. As long as the node holds the channel, the call lives, even if the browser WebSocket or the Fabric momentarily goes away. More on that under resilience below.
mod_fabric: the FreeSWITCH side
On the FreeSWITCH node, a custom endpoint module, mod_fabric, maintains the gRPC stream to the Fabric and builds the inbound/outbound channels that bridge WebRTC endpoints to the rest of your telephony: SIP phones, carrier trunks, and customer BYOC. It is a drop-in peer to mod_verto, so calls route through your existing FreeSWITCH dialplan exactly as before.
What you get: capabilities and benefits
No server affinity
Any FreeSWITCH instance can handle media from any WebRTC endpoint. New calls fan out freely across your whole node pool instead of piling onto whichever server an endpoint happened to register with. You scale out, not just up.
Multi-AZ by design
FreeSWITCH pools trunk across availability zones. A browser in one AZ can be bridged by a node in another, and if an entire zone goes dark, new calls simply route to healthy nodes elsewhere. Resilience stops being a bolt-on and becomes a property of the topology.
Nearest-PoP routing
WebRTC endpoints, including browsers, mobile apps, and live agents, connect to the closest point of presence, minimizing the first-hop latency that WebRTC users feel most. Media then flows to the best available FreeSWITCH node behind that edge.
One path for every endpoint
Browsers, mobile apps on iOS and Android, and contact-center agents on the WebRTC side; SIP phones, carrier trunks, and customer BYOC on the telephony side. All are bridged by the same Fabric. One integration surface supports every kind of endpoint you run.
Built for resilience, not just scale
Removing affinity would be hollow if a hiccup dropped calls. Because the Fabric is never in the media path, recovery almost always means re-establishing signaling without disturbing the media, and that is a much easier problem.
- The node holds the call and the RTP. As long as the node lives, the call lives, even through a browser refresh or a brief Fabric interruption.
- Browser reconnect and reattach. If an agent refreshes the page or drops their connection, they reconnect, potentially to a different Fabric instance, and the live call is re-offered and rebuilt in both directions while the node keeps its side of the media warm.
- Node-failure cleanup. When a node stream goes down, the Fabric detects it, tears down the affected call records, and notifies the browser rather than leaking a zombie leg.
- Crash-safe call state. Durable call state backed by Redis in the multi-instance topology lets a call survive a load-balancer bounce or an instance restart well enough to reattach or be cleanly reaped.
In short: media is anchored to the node, the browser is a thin replaceable signaling client, and the Fabric is a translator that can come and go. That division of labor is what makes the system forgiving.
Built for horizontal scale
We load-tested the signaling path end to end, with thousands of synthetic Verto agents driving real login and call setup through the real mod_fabric gRPC client, and learned exactly where the limits are. The ceiling is not CPU or node count; it is the coordination work a single instance does. The fix is simply more Fabric instances, each carrying a share of the agents and calls.
That is the multi-instance design at the heart of Media Fabric: a clustered set of Fabric instances, so an agent WebSocket on one instance can transparently reach a node stream on another, plus durable, shared call state. In load testing, capacity scaled near-linearly as instances were added, cleanly handling tens of thousands of concurrent agents. Because the Fabric never carries media, scaling signaling is cheap. You add instances behind a load balancer, not media relays.
A drop-in for mod_verto
Media Fabric speaks the Verto surface your clients already know: login, invite/answer/attach/bye, in-call DTMF in both directions, hold/unhold, blind and attended transfer, event channels and conference liveArray, plus JWT (HS512) authentication at login. FreeSWITCH-to-browser invites carry the real caller ID read off the channel. For most WebRTC clients, pointing at the Fabric instead of mod_verto is a configuration change. You gain affinity-free routing without rewriting your front end.
The wire protocol is deliberately kept a swappable front end, which is also our path toward SignalWire SDK compatibility down the road.
What this means for CCaaS and CPaaS platforms
For a cloud contact-center or communications platform, breaking FreeSWITCH server affinity changes what is operationally possible:
- Scale across geographically distributed infrastructure without standing up a separate silo per region.
- Let remote agents connect from anywhere and stay centrally managed, with no "which server is this agent on?" bookkeeping.
- Survive zone failures because no endpoint is hostage to a single box or a single availability zone.
- Run true horizontal autoscaling and rolling upgrades because live media is not chained to the instance you want to drain.
No regional silos. No per-server lock-in. Just WebRTC endpoints that are genuinely reachable from anywhere, on infrastructure that scales out and survives zone failures.
Frequently asked questions
What is FreeSWITCH server affinity?
Server affinity is the coupling that pins a WebRTC endpoint, using Verto or SIP, to the single FreeSWITCH server that terminated its media. All of that call DTLS-SRTP keys, ICE candidates, and RTP flow belong to that one instance, so media can only move to and from that box.
How does IQAAI Media Fabric remove affinity?
The Fabric separates signaling from media. Endpoints hold one durable WebSocket to the Fabric, not to any FreeSWITCH node. The Fabric brokers Verto signaling to and from FreeSWITCH nodes over gRPC, and the actual audio/video flows directly between node and browser. Because the Fabric negotiates each call rather than tying an endpoint to a server, any node can serve any endpoint.
Does media flow through the Fabric?
No. The Fabric is never in the media path. It only translates signaling. DTLS-SRTP/ICE media flows directly between the FreeSWITCH node and the WebRTC endpoint. That keeps the Fabric lightweight and independently scalable.
Is it compatible with existing FreeSWITCH deployments and Verto clients?
Yes. mod_fabric is a FreeSWITCH endpoint module that routes through your existing dialplan alongside mod_verto, and the Fabric speaks the same Verto protocol to clients, so standard WebRTC front ends work with minimal changes.
How does it handle failover and browser refreshes?
Because the node holds the media, the call survives signaling interruptions. A browser that refreshes or reconnects, even to a different Fabric instance, reattaches to its live call, and durable call state lets calls survive load-balancer bounces and instance restarts.
How does it scale?
Horizontally. You run multiple clustered Fabric instances behind a load balancer, each carrying a share of agents and calls, with shared durable call state. Load testing showed near-linear scaling as instances are added, since no media ever traverses the Fabric.
The bottom line
FreeSWITCH server affinity has quietly shaped how communications platforms are built for years, dictating how you scale, how you fail over, and how you distribute across regions. IQAAI Media Fabric removes that constraint by splitting signaling from media and keeping the Fabric out of the RTP path entirely. Any FreeSWITCH node in any availability zone can bridge any WebRTC endpoint, at the nearest edge, with no per-server lock-in.
The payoff is infrastructure that scales horizontally, survives zone failures, and serves browsers, mobile apps, live agents, SIP phones, and carrier trunks over one path, exactly what a modern, globally distributed CCaaS platform needs.
Want to see IQAAI Media Fabric in your environment, or go deeper on the architecture? Get in touch with our team.
Discussion0
Join the conversation
Sign in with your preferred account to comment, reply, and keep the discussion useful for other engineers.
Takes a few seconds. No separate password required.