An Easy and Straightforward (but Deeper) Dive into WebRTC
In the previous post, we covered the basics of WebRTC with a peer-to-peer focus and built a simple two-person video call app. At the the…
An Easy and Straightforward (but Deeper) Dive into WebRTC

In the **previous post, we covered the basics of WebRTC with a peer-to-peer** focus and built a simple two-person video call app. At the the end, we raised some key questions:
-1) “How do two peers connect/find each other?”
- “What if we want more than two people in a call?”
In this article, I’ll answer some of those questions, with a focus on how WebRTC makes connections, and then in part 2, I’ll cover how to handle multi-user calls in WebRTC by telling two main approaches: SFU (Selective Forwarding Unit) and MCU (Multipoint Control Unit).
But… but … first, let’s step back and review clearly and easily a bit more about the WebRTC architecture itself — especially how it deals with connection setup, NAT traversal, and protocols like ICE, STUN, and TURN. in the end, after reading these two post, you will understand the general concepts of WebRTC and how useful it can be Then, you can freely jump to the main reference of WebRTC.
Part 1
Easy Overview of WebRTC Architecture and Protocols
So we can say: “WebRTC is browser engine for real-time media” — if the browsers know how to locate and talk to each other, they can deliver voice, video, or data with minimal delay.
But each peer is just a simple device, and they are not like the server that has a unique IP, so the question is HOW?
Question 1) How do two peers connect/find each other?

When two peers (say, Alice and Bob) try to connect over the internet, they might be behind routers or firewalls — also known as NAT devices (Network Address Translation). NAT devices provide a layer of security, yet they also hide your actual IP from the open internet. That’s good for safety but tricky for P2P calls.
— By NAT Traversal:
WebRTC solves this using NAT traversal techniques — specifically ICE (Interactive Connectivity Establishment). ICE tries various ways to reach the other peer. For example:
Imagin Alice is at home on her laptop, and Bob is in a coffee shop on his phone. Both are behind NAT routers:
- Alice has a local IP: something like
192.168.x.x - Bob has a local IP: something like
10.0.x.x
These addresses are private — they only work inside their respective networks. From the internet’s perspective, each user’s router has a public IP, but that IP doesn’t magically map them to each other.
So how do they connect directly?
[Phase A]. Gathering Addresses (ICE Candidates)
- Local (Host) Candidates:
Each browser notices, “Hey, I have a local IP:
192.168.x.x.” That’s one possible route — it might work if both users are on the same Wi-Fi network (like in a small office). - STUN Candidates: The browsers each contact a STUN server on the internet, asking, “What’s my public IP and port?”
- The STUN server replies, for example, “Your public IP is 45.67.89.100, port 56789.”
- Now Alice’s browser knows it could be reached via
45.67.89.100:56789(assuming the router permits traffic).
These possible IP+port options are called ICE candidates.

Should I provide a STUN server?
… in many small/medium projects, you can rely on public STUN services (like Google’s free server: stun:stun.l.google.com:19302).
Does the NAT with STUN server always find the ICE?
— “NO” ! … As i’ve investigated ,for full production, around 10–20% of calls can fail NAT traversal and need to fallback to TURN server.
3. TURN Candidates:
If a TURN server is provided, the browser also obtains a “relay” candidate. This basically says, “If direct attempts fail, you can send media through me at TURN_SERVER_IP.”
A TURN server relays all audio/video data when a direct P2P path can’t be established (e.g., behind strict firewalls).
Do I need one?
If you don’t provide a TURN server, those calls might just fail. You can run your own TURN server (e.g., coturn) or use a third-party service (like Twilio or Xirsys)
Example WebRTC Config with TURN and STUN server
const config = {
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{
urls: "turn:your-turn-server.com:3478",
username: "turnUser",
credential: "turnPassword"
}
]
};
const peerConnection = new RTCPeerConnection(config);
[ Phase B ]. Exchanging Candidates via Signaling
- Alice and Bob share their ICE candidates over the signaling Server(which I described in the last post) (by a WebSocket).
- So Bob learns:
- “Alice can possibly be reached at
192.168.x.x:3333(local) o45.67.89.100:56789(public), or a TURN fallback.” - Alice learns Bob’s set of addresses likewise.
[ Phase C ]. Testing the Routes
The ICE process systematically tries each combination:
- Alice tries Bob’s public IP candidate, Bob tries Alice’s.
- If that fails (e.g., blocked by a strict firewall), they try any TURN candidate
[ Phase D ]. P2P Is Established!
Once a working path is found, real-time audio/video can flow. The clean part is that Alice and Bob don’t have to know all these details. The browser handles the ICE logic behind the scenes — it just needs the STUN/TURN servers and the candidate exchange.
That’s how WebRTC deals with NAT and firewalls: by trying every known route until one succeeds. It’s a bit like knocking on all possible doors until you find the one that opens.
Is it finished? … still sth should be clear!
How Do Peers Agree on Media Details?
Even if two peers can reach each other over the network, they still need to agree on how to send audio/video. For instance, do we use VP8 or H.264 for video? Do we want stereo or mono audio? This is where the SDP (Session Description Protocol) steps in.
- The caller sends an SDP offer describing what formats/codecs it supports.
- The callee returns an SDP answer showing which formats it can use.
When both sides have each other’s SDP, they know exactly how to encode and decode media.
So … Putting It All Together
Peer A and Peer B use a small signaling server to exchange:
- SDP Offer/Answer (the “how” of media)
- ICE Candidates (the “where” of media)
Part 2
Question 2) What if we want more than two people in a call?

When we are only connecting two peers (Alice and Bob), peer-to-peer is perfect. But what happens when you add a third person or a whole group? A simple mesh of P2P links can quickly become chaotic :(
- Bandwidth Overload: Each user sends/receives multiple full-quality streams (one for every participant).
- CPU Strain: Encoding/decoding multiple video streams can overload the browser, especially on lower-end devices.

To solve this, real-world apps use a media server in the middle. Specifically, two main architectures are common:
- SFU (Selective Forwarding Unit)
- MCU (Multipoint Control Unit)
SFU (Selective Forwarding Unit)
In an SFU architecture, everyone sends their audio/video to a central server that forwards those streams to the other participants — typically without mixing or transcoding.
- Each participant sends one outgoing video stream to the SFU server.
- The SFU selects which streams to forward to whom. (For example, it might forward all streams to each participant or only the active speaker’s stream.)
- Each participant then receives multiple streams (one from each of the other participants).

Why use SFU?
- Scalability: Upload bandwidth is minimized. Each user only uploads once, not N-1 times.
- Lower Server Cost: The SFU doesn’t do heavy mixing, so CPU usage on the server is less than an MCU.
- Flexibility: Clients can subscribe to different resolutions (e.g., watch the active speaker in HD, others in low resolution).
Downside:
- Each client must handle/decode multiple incoming streams. That might be a burden if there are many participants.
- Some basic complexity: you must manage who receives whose stream (like “pin” the speaker, etc.).
MCU (Multipoint Control Unit)
In an MCU architecture, the server actively mixes or composites all incoming video feeds into one combined stream.
- Each participant sends one outgoing video stream to the MCU server.
- The MCU decodes all incoming streams, mixes them (e.g., a 2x2 grid for four users), and re-encodes them into a single stream.
- Each participant then receives just that single mixed stream.

Why use MCU?
- Client Simplicity: Every participant just deals with one stream (the mixed grid). Great for low-power devices.
- Unified Layout: The server can do fancy layouts or overlays, so everyone sees the same “mosaic.”
Downside:
- High Server Load: Mixing and re-encoding multiple video streams is CPU-expensive.
- Less Flexible: Everyone sees the same composite. If you want individual control (like switching layouts or selecting only certain streams), that’s more complicated.
So … Which Approach to Choose?
- SFU is often used by apps like Zoom, Google Meet, and other conferencing solutions. Why? It’s more efficient for medium-sized groups, and each participant can receive different quality levels for each stream.
- MCU can be used if you want the simplest client experience or a consistent, single layout — but it’s expensive on the server side.
In fact, some commercial solutions do a hybrid: audio is mixed (like an MCU) for simplicity, but video is forwarded (like an SFU) for efficiency.
In Summary …
SFU = Light server load, multiple streams to each client, flexible subscriptions
MCU = Heavy server load, one mixed stream to each client, simpler for participants
Some Key Questions About SFU/MCU…
Will an SFU or MCU handle all our signaling responsibilities?
- No. we still need your original signaling server (like in the P2P case) to let users join a room and discover the SFU/MCU’s address.
Does adding SFU/MCU mean no more peer-to-peer?
- Yes, effectively. Media flows through the server, not directly. However, it’s still WebRTC under the hood, just that the server is now an intermediary.
How do I implement an SFU or MCU?
- We can build one from scratch using frameworks like Janus, Kurento, mediasoup, or Jitsi. Or adopt a cloud-based service if we want a managed solution.
Which is best for large events or webinars?
- Typically an SFU approach is more scalable for large rooms (e.g., 20+ participants), because the server just forwards streams. An MCU would need massive CPU to mix so many feeds.
What about screen sharing in group calls?
- Both SFU and MCU handle it fine. Screen-sharing is just another video track. But in an SFU, each participant can choose the resolution of the screen share. In an MCU, it’ll be composed into the grid.
메타데이터
- post_id
- 5faf4a17d705
- slug
- an-easy-and-straightforward-but-deeper-dive-into-webrtc-5faf4a17d705
- url
- https://medium.com/@salimian/an-easy-and-straightforward-but-deeper-dive-into-webrtc-5faf4a17d705
- canonical_url
- https://medium.com/@salimian/an-easy-and-straightforward-but-deeper-dive-into-webrtc-5faf4a17d705
- author_url
- https://medium.com/@salimian
- status
- ok
- fetched_at
- 2026-06-26 03:39:16