A two-person WebRTC call is peer-to-peer: Alice sends video directly to Bob and vice versa. A ten-person call can’t work the same way: each participant would need to send 9 video streams and receive 9 streams, consuming 9x the upload bandwidth of a one-to-one call. Group video calls require a media server. There are two architectures: SFU (Selective Forwarding Unit) and MCU (Multipoint Control Unit). The choice determines server cost, client CPU usage, and call quality.

MCU: Mix Everything Server-Side#

An MCU receives all participants’ streams and composites them into a single mixed stream that it sends to each participant. From Alice’s perspective: she sends one stream to the server, receives one stream from the server. Simple for the client.

The server does the heavy lifting: decoding all incoming streams, compositing them into a layout (grid, speaker view), and re-encoding into one output stream per participant. At 10 participants: decode 10 streams, encode 10 outputs. CPU cost scales as O(N²) at the server. MCUs are expensive to run at scale.

SFU: Route Selectively Server-Side#

An SFU receives all participants’ streams but does not decode or mix them. It selectively forwards each stream to the appropriate recipients. Alice sends one stream to the SFU; the SFU forwards it to the other 9 participants. Each participant receives N-1 separate streams.

The client does the layout: receiving 9 streams and rendering them in a grid. Client CPU cost scales with participant count. Server cost is much lower: no decoding or re-encoding, just packet forwarding.

graph TD A[Alice: 1 stream up] --> S[SFU Server] B[Bob: 1 stream up] --> S C[Carol: 1 stream up] --> S S --> A2[Alice receives: Bob + Carol streams] S --> B2[Bob receives: Alice + Carol streams] S --> C2[Carol receives: Alice + Bob streams] style A fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style B fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style C fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style S fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style A2 fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style B2 fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style C2 fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff

Simulcast and Bandwidth Adaptation#

SFUs use simulcast: each client sends the same stream at multiple quality levels (high, medium, low). The SFU forwards the appropriate quality tier to each receiver based on their available bandwidth. A receiver on a slow connection gets the low-quality tier; one on a fast connection gets high quality. This per-receiver adaptation is impossible with MCU (which sends one mixed stream to everyone).

Zoom uses SFU architecture. The client renders up to 49 video tiles. For very large calls (100+ participants), the SFU only forwards streams for visible participants — the rest are paused.

When MCU Makes Sense#

MCU is appropriate when client CPU is severely constrained (old mobile devices) or when you need to record a call as a single composited video stream for storage. Recording a group call as N separate streams and compositing offline is usually cheaper than running a live MCU, so most modern systems use SFU with offline recording composition.

At Salesforce#

Salesforce had an internal video meeting product before switching to Zoom. The early version used an MCU for simplicity: one encoded stream per participant, server does all composition. At 20-person all-hands calls, the MCU server consumed 8 CPU cores per call. Switching to an SFU-based architecture dropped server CPU by 85% per call. Client CPU increased but modern laptops handled it without issue.

What I’m Learning#

SFU is the right default for group calls: lower server cost, better per-receiver quality adaptation via simulcast. MCU makes sense only when client capability is the constraint. Most modern video conferencing products (Zoom, Meet, Teams) are SFU-based with MCU used only for specific recording or compatibility scenarios.

Have you worked on video conferencing infrastructure, and what drove the SFU vs MCU decision in your system?