Why mezon-sfu: Building Real-Time Media Infrastructure the Hard Way
We didn’t start here. Mezon’s client began on React Native and Electron, and for a while that made sense - one codebase, fast iteration, ship everywhere. But some of the bugs we hit were rooted in the hybrid layer itself: platform-bridge quirks and limitations we couldn’t fix from our side no matter how much time we put into them. Eventually we made the call to rewrite the clients as fully native mobile and native desktop apps, trading development speed for actually being able to fix what was broken.
On the server side, we started with LiveKit. It got us moving quickly, but real usage exposed its own set of hard limits: memory usage on Linux climbed too high over the course of long-running calls, the LiveKit mobile SDK’s own dependencies meant older devices simply couldn’t be supported, and some bugs we ran into just never got resolved upstream. We were building against someone else’s constraints instead of our own product’s needs.
mezon-sfu is what came out of deciding to stop working around those limits and own the stack instead. Most teams building a video chat product reach for an existing SFU - mediasoup, Janus, LiveKit - and there are good reasons to do that. We’d already tried that path. Here’s what building mezon-sfu from scratch, in C, on io_uring, actually buys us.
A hot path with no locks in it
- Each worker has its own send ring, its own inbox, and its own view of which sessions it owns.
- Room membership is published through RCU-style immutable snapshots - a worker forwarding RTP takes one atomic pointer load, walks a snapshot that can never change underneath it, and never blocks on a mutex to do it.
- Cross-worker delivery goes through a lock-free fan-out mesh - one SPSC ring per (source, destination) worker pair - so no worker ever waits on another to hand off a packet.
The result: adding participants to a room doesn’t add lock contention to the packets already flowing through it.
io_uring and zero-copy, actually used correctly
mezon-sfu is built on io_uring end to end - provided buffer rings for ingress, IORING_OP_SEND_ZC for egress — because a media server’s real workload is moving bytes, not making syscalls. Packets are received into kernel-managed buffer pools and referenced, not copied, until they’re forwarded; kernel buffer indices are returned to their owning ring by the thread that owns it, never cross-thread.
Server-as-offerer, ICE-lite by design
mezon-sfu always sends the offer and never negotiates ICE actively - the server is the fixed point, clients answer. This isn’t just simpler to implement; it’s simpler for every client that ever has to talk to it. No offer glare, no negotiation races, and renegotiation (a peer joining, leaving, or changing role) is just a matter of publishing a new snapshot and pushing a fresh offer.
Multi-codec with graceful fallback, not codec lock-in
The SDP layer offers VP9, AV1, and VP8 in a single negotiation, in preference order, and lets ordinary RFC 3264 offer/answer semantics pick whichever the client actually supports - no server-side capability detection logic required. A client that can’t do VP9 falls back to VP8 automatically, with no special-casing anywhere else in the stack.
Congestion control that closes the loop in both directions
mezon-sfu implements transport-wide congestion control (TWCC) feedback generation for the uplink - publishers get real per-packet arrival feedback from the SFU itself, not just from downstream subscribers - alongside standard downlink TWCC parsing feeding a GCC-style bandwidth estimator. Combined with VP9 SVC layer selection, a subscriber’s available bandwidth can drive which spatial/temporal layer they actually receive, independent of what every other subscriber in the room is getting.
Built for Mezon’s actual shape, not a generic SFU
Two features that fell straight out of real product requirements rather than being generic SFU checkboxes:
- Speaker/audience roles, Push To Talk style - audience members skip keyframe gating, SVC scheduling, and GCC bookkeeping entirely, because they never publish. That’s not a flag bolted onto a generic subscriber path; it’s a structurally cheaper path for the common case of large rooms with few active speakers.
- NATS-native event integration - room and participant lifecycle events (join, leave, publish, room teardown) are first-class outbound events, not something bolted on with a webhook afterthought.
The honest tradeoff
None of this is free. Owning the whole stack - DTLS, SRTP, RTP/RTCP demux, congestion control, SVC layer selection - means owning every bug in it too, and there have been plenty along the way. That’s the cost of control: mezon-sfu isn’t trying to be a general-purpose SFU for every WebRTC use case. It’s trying to be exactly the SFU Mezon needs, with no abstraction layers between “what the product requires” and “what the server does.”
------------------------------------------------
MEZON - YOUR CLAN, YOUR WORLD!
A product proudly developed by the engineers at NCCPLUS.
🌐 Website: https://mezon.ai/
📧 Email: hello@mezon.vn
📞 Hotline: 024.6687.4606
📲 Available on App Store & Google Play