← System design

Communication

Design Video Conferencing

A video call feels broken the moment a reply arrives half a second late, so this is a system built against the clock rather than for throughput. You have to move live audio and video between people on different networks and continents in about a quarter of a second, keep going when someone's Wi-Fi collapses, and do it for millions of meetings at once without a server that decodes every stream.
Core: edge SFUs with simulcast and per-viewer layer choice25M people in calls at peakMouth-to-ear under 250 msThree planes: control, signalling, media

01

The problem

01

The problem

Picture a weekly team meeting: nine people, three countries, two on laptops in offices, one on a phone in a car, and one sharing a slide deck. Each of them sends one camera and one microphone, and each wants to see and hear everyone else with no noticeable delay. When the person in the car drives under a bridge, everyone else should notice nothing at all.

The naive design, every client sending its stream to every other client, needs each laptop to upload eight copies of its video. Mixing all the streams on a server into one picture fixes upload but means decoding and re-encoding every stream for every meeting, which is ruinously expensive and adds delay. The design that wins in practice sits between them: a server that forwards packets without decoding them, and lets each viewer receive only what its screen and network can use.

The core question

How do you get each participant's media to every other participant within 250 ms, when their networks differ by a factor of a hundred and change from second to second?

02

What the platform must do

02

What the platform must do

Functional
  • Start or join a meeting from a link, with 1:1 calls and group calls of up to 500 people, and up to 49 videos on one screen.
  • Send camera, microphone and screen share; receive the active speaker in high quality and others as thumbnails.
  • Host controls: waiting room, mute others, remove a participant, lock the meeting.
  • In-meeting chat, reactions and raised hands delivered to everyone within a second.
  • Optional cloud recording that produces a file shortly after the meeting ends.
  • Dial-in by phone for participants without data.
Non-Functional
  • Mouth-to-ear latency under 250 ms at p95 for participants on the same continent, under 400 ms across oceans.
  • Join time from click to seeing video under 3 seconds.
  • Audio survives up to 20% packet loss with intelligible speech; video degrades gracefully instead of freezing.
  • A media server failure costs participants at most a few seconds of interruption, never the meeting.
  • Media is encrypted in transit always, with an end-to-end option where the servers cannot decrypt anything.
Scope it early

Ask about maximum meeting size, whether webinars with thousands of passive viewers are in scope, and whether end-to-end encryption is required by default. Large webinars push you towards a streaming-style fan-out tree; default end-to-end encryption rules out server-side recording and transcription. Both change the architecture, so settle them before drawing.

03

Sizing the media load

03

Sizing the media load

Assume 25 million people in calls at the daily peak, an average meeting of six participants, and a typical receive budget of four visible videos plus audio. About 15% of participants are behind networks that block UDP and must be relayed over TCP.

QuantityWorkingResult
Concurrent participantsassumption25M
Concurrent meetings25M / 6about 4.2M
Upload per participantsimulcast: 1.2 Mbps + 350 kbps + 120 kbps, plus 40 kbps audioabout 1.7 Mbps
Download per participantone large video at 1.2 Mbps + three thumbnails at 120 kbps + audioabout 1.6 Mbps
Total media egress from servers25M x 1.6 Mbpsabout 40 Tbps
Media ingress to servers25M x 1.7 Mbpsabout 42 Tbps
Forwarding servers needed40 Tbps / 5 Gbps usable per serverabout 8,000, plus 30% spare
Packets forwarded per second40 Tbps / about 1,100 B per packetabout 4.5 billion
Relayed participants25M x 15% on TURN over TCP 443about 3.75M, 6 Tbps through relays
Join storm at the top of the hour35% of meetings start within 3 minutesabout 50,000 joins / s
Recording storage5% of meetings, composite 720p at 1.5 Mbpsabout 140 TB / day
What the arithmetic tells you

40 Tbps of egress is larger than most CDNs carry, and none of it can be cached because every packet is new and wanted only by a few people. Cost and quality are both decided by how close the forwarding server is to each participant and by how few bits you send each viewer.

The cheap part

Signalling is tiny. Even the join storm is 50,000 small messages a second, a modest WebSocket fleet. Spend your interview time on media, not on the REST API.

04

API and signalling

04

API and signalling

Meeting management over REST

POST/v1/meetingsSchedule or start a meeting
{ "topic": "Design review", "start": "2026-10-02T10:00:00+05:30", "settings": { "waiting_room": true, "e2ee": false, "max_video": 25 } } // 201 Created { "meeting_id": "m_4418-2207", "join_url": "https://meet.example/j/4418-2207?pwd=..." }
POST/v1/meetings/{meeting_id}/joinGet a join ticket and the nearest media edge
// The client sends its measured latency to a few candidate edges { "display_name": "Priya", "probes": { "bom1": 18, "sin2": 61, "fra1": 134 } } // 200 OK { "ticket": "eyJhbGciOi...", // short-lived, signed, names meeting, user and role "signal_url": "wss://sig-bom1.meet.example/v1", "ice_servers": ["stun:bom1.meet.example:3478", "turns:bom1.meet.example:443"] }

Signalling over a WebSocket

GETwss://sig-bom1.meet.example/v1Real-time control channel
// client to server: offer its media description { "type": "publish", "sdp": "v=0 ... a=simulcast:send h;m;l ..." } // server to client: someone joined, here are their tracks { "type": "participant_joined", "id": "p_19", "tracks": ["audio", "video"] } // client to server: what I want to receive, re-sent when the layout changes { "type": "subscribe", "wants": [{ "id": "p_19", "max_height": 720 }, { "id": "p_07", "max_height": 180 }] } // either direction: host actions, chat, reactions, all with a sequence number { "type": "mute_request", "target": "p_07", "seq": 311 }
Three channels, three jobs

REST handles things that can take a second: scheduling and tickets. The WebSocket carries small control messages that must arrive in order. Media never touches either; it flows as encrypted RTP over UDP between the client and its media edge, set up by the SDP the signalling channel exchanged.

05

Architecture overview

05

Architecture overview

Control, signalling and media planesDiagram
flowchart LR
	C1["Participant A"] -->|"REST: join"| API["Meeting API"]
	API --> MDB[("Meetings DB")]
	API --> PL["Placement service"]
	C1 -->|"WebSocket"| SG["Signalling gateway"]
	SG --> RS[("Room state")]
	C1 ==>|"RTP over UDP"| E1["Edge SFU Mumbai"]
	C2["Participant B"] ==>|"RTP over UDP"| E2["Edge SFU Frankfurt"]
	E1 <==>|"backbone cascade"| E2
	C3["Participant C, UDP blocked"] --> T["TURN relay on 443"]
	T ==> E1
	E1 -. "streams" .-> REC["Recording workers"]
	REC --> OBJ[("Object storage")]

Think of the system as three planes with very different properties. The control plane is ordinary web software: accounts, scheduling, the meetings database and the placement service that decides which media server hosts a meeting. It can tolerate a few hundred milliseconds of latency and is deployed in a handful of cloud regions.

The signalling plane keeps one WebSocket per participant. It tells clients who is in the room, exchanges the session descriptions that set up media, and carries host actions, chat and reactions. Room state, such as the participant list and who is muted, lives in a small replicated store keyed by meeting ID, so any signalling node can serve any room.

The media plane is where all the bandwidth goes. It is a fleet of selective forwarding units at about 60 edge locations, close to where people are. Each participant connects to its nearest edge. If all participants share an edge, one SFU forwards everything; if they are spread across continents, the edges they use are cascaded over a private backbone, so each stream crosses an ocean once rather than once per viewer.

Placement service

Chooses an SFU for each participant from the client's latency probes, server load and where the meeting already lives. It keeps a meeting on as few edges as possible while keeping each person under about 40 ms from their edge.

Edge SFU

Receives each sender's simulcast layers, picks a layer per receiver, and forwards packets after rewriting headers. It does not decode video, so one server can forward several thousand streams.

TURN relay

For networks that block UDP, the client tunnels media over TLS on port 443 to a relay next to the SFU. It costs latency, so it is a fallback, not the default.

Recording workers

Subscribe to a meeting like a silent participant, decode the streams and compose a single file. Decoding happens here, off the live path.

06

Deep dive: moving media in real time

06

Deep dive: moving media in real time

1. Why a forwarding server, not a mixer or a mesh

TopologyHow it worksVerdict
Mesh (peer to peer)Each client sends its stream to every other client.No servers to run and the lowest latency for two people. Upload grows with every participant; at five people a phone is sending four videos.
MCU (mixing server)The server decodes all streams, composes one picture and encodes it per viewer.Each client receives a single stream, which helps very weak devices. The server burns CPU on every pixel and adds 100 ms or more of delay.
SFU (forwarding server)The server forwards packets and chooses which stream each viewer gets.Clients upload once and the server never decodes. This is the default for group calls.

Production systems mix them. A 1:1 call starts peer to peer for the lowest latency and switches to an SFU when a third person joins or when the direct path fails. Phone dial-in goes through a small audio mixer, because a phone line can only carry one mixed audio stream.

2. Simulcast and choosing a layer for each viewer

Each sender encodes its camera three times: a high layer at 720p, a medium layer at 360p and a low layer at 180p. The SFU receives all three and sends each viewer the one that fits. A viewer with the speaker in a large tile gets the high layer; a viewer showing that person as a thumbnail gets the low layer; a viewer whose network is struggling gets whatever fits under its estimated bandwidth.

Switching layers cleanly needs care. The SFU can only switch a viewer to a new layer at a keyframe, so it asks the sender for one with a picture loss indication and switches when it arrives. It also rewrites sequence numbers and timestamps so the receiver sees one continuous stream. With codecs that support scalable video coding, such as VP9 and AV1, the layers are nested inside one stream and the SFU can drop the upper layers without waiting for a keyframe.

3. A bandwidth ladder per receiver

Every receiver runs congestion control, typically Google's GCC or a transport-wide feedback variant, which estimates available bandwidth from packet arrival times and loss. The SFU reads that estimate and walks a ladder, from the richest experience down to the minimum that still works:

Estimated bandwidthWhat the viewer getsTypical situation
Above 3 MbpsSpeaker at 720p, up to 8 thumbnails at 180p, screen share at full resolutionFull experience
1.5 to 3 MbpsSpeaker at 720p, thumbnails reduced to 4Most office and home networks
600 kbps to 1.5 MbpsSpeaker at 360p, thumbnails paused except the previous speakerBusy Wi-Fi, good mobile
200 to 600 kbpsSpeaker at 180p, screen share frame rate cut to 2 per secondWeak mobile
60 to 200 kbpsNo video, avatars only, audio at full qualityVery poor networks
Under 60 kbpsAudio at a lower bitrate with heavy forward error correctionLast resort before the phone fallback
Audio is sacred

Audio costs 30 to 50 kbps and video costs fifty times that. Every step on the ladder sheds video before it touches audio, because people tolerate a frozen picture far better than broken speech.

4. Getting through NATs and firewalls

Most clients sit behind NAT and cannot receive inbound packets from a server they have not contacted. WebRTC solves this with ICE: the client gathers candidate addresses, including its public address learned from a STUN server, and tests which ones reach the SFU. Because the SFU has a public address, a direct UDP path works for about 85% of participants. The rest are behind corporate firewalls or strict NATs and fall back to TURN over TLS on port 443, which looks like ordinary HTTPS traffic. That path adds 10 to 30 ms and suffers when packets are lost, because TCP retransmits audio that is already too late to play.

5. Living with loss and jitter

Packets on the internet arrive late, out of order or not at all. The receiver keeps a jitter buffer that holds packets for 20 to 80 ms and adapts its size to measured jitter: bigger means smoother playback but more delay. For lost video packets the receiver sends a NACK and the SFU, which keeps a few hundred milliseconds of recent packets, retransmits from its own buffer; this is fast because the SFU is only one short hop away. Audio uses Opus with in-band forward error correction, and when a packet is truly gone, packet loss concealment synthesises a few milliseconds of plausible sound.

6. Cascading for global meetings

If a meeting has people in Mumbai, Frankfurt and São Paulo, forcing everyone onto one SFU makes two of the three groups cross an ocean on the public internet. Instead, each group connects to its local edge, and edges exchange streams over a private backbone. An edge forwards each remote sender's stream once to each other edge, whatever the number of viewers there. That keeps every participant's first hop short, routes long distances over a managed network, and turns a meeting into a small tree of servers.

A three-region meetingDiagram
flowchart LR
	subgraph IN["Mumbai edge"]
		A1["4 participants"] --> S1["SFU"]
	end
	subgraph EU["Frankfurt edge"]
		B1["3 participants"] --> S2["SFU"]
	end
	subgraph BR["Sao Paulo edge"]
		C1["2 participants"] --> S3["SFU"]
	end
	S1 <-->|"one copy per stream"| S2
	S2 <-->|"one copy per stream"| S3
	S1 <-->|"one copy per stream"| S3

7. Encryption and who can see the media

By default every stream is encrypted with DTLS-SRTP between the client and the SFU. The SFU can read headers it needs for forwarding, and it could decrypt the payload, which is what makes server-side recording and live captions possible. With end-to-end encryption turned on, clients add a second layer of encryption to each frame using keys the server never sees, through insertable streams and a scheme such as SFrame. The SFU still forwards packets and chooses layers from unencrypted metadata, but recording, transcription and phone dial-in stop working, which is why it is usually an opt-in setting.

8. Recording

A recording worker joins the meeting as a hidden participant on the same SFU and subscribes to everything. It writes the raw media to durable storage in short segments first, so a crash loses at most a few seconds, then composes them into one layout and encodes the final file after the meeting. Keeping composition off the live path means a busy recording cluster can never make a call worse.

07

Decisions and their costs

07

Decisions and their costs

Chosen
SFU with simulcast

Upload once, receive only what fits, no decoding on the server. Clients do more work, decoding several streams, which modern phones handle easily.

Default for groups
Rejected
MCU mixing for everyone

Simple for clients, but decoding and re-encoding every stream costs many times the CPU, adds delay and locks every viewer into one layout.

Only for phone bridges
Chosen
UDP with application-level recovery

Late audio is useless, so the transport must not wait for retransmissions it did not ask for. NACK for video, FEC for audio and a jitter buffer give control over every millisecond.

Fits real-time media
Rejected
TCP for all media

Works through every firewall, but one lost packet stalls everything behind it. Fine as a fallback through TURN, poor as the default.

Fallback only
Chosen
Transport encryption by default, end-to-end as an option

Keeps recording, captions and dial-in working for the many meetings that need them, while giving sensitive meetings a mode where the servers see nothing.

Practical balance
Alternative
End-to-end encryption always on

Strongest privacy, and some products choose it. You give up server features and make key management for large meetings much harder.

Depends on the product
Chosen
Many edge locations with a private backbone

Each person is a short hop from an SFU, and long distances travel over a managed network with predictable latency. Costs more in operations than a few big regions.

Quality where it counts
Alternative
A few large cloud regions

Far easier to run and good enough within one continent. Intercontinental meetings suffer from public internet routing.

Good starting point

08

Failure modes

08

Failure modes

💥
An SFU crashes mid-meeting

Two hundred meetings on one server lose their media at once. Signalling is still up, so clients know something is wrong within a second.

Placement assigns a new SFU, signalling tells clients to republish, and ICE restarts on the new server. Meetings recover in 2 to 4 seconds. Keep 30% spare capacity per edge so there is room to absorb a lost server.
🌐
A whole edge location goes dark

A fibre cut or power event takes down an edge holding a few hundred thousand participants.

Clients already hold latency probes for the next nearest edges. Placement moves them there and cascades are rebuilt. Expect a short interruption and slightly higher latency, not a dropped meeting.
📶
A participant's Wi-Fi collapses

Loss jumps to 25% and bandwidth falls below 300 kbps. If nothing adapts, the client keeps sending 1.7 Mbps, queues fill, and everything gets worse together.

Congestion control cuts the send rate within a second, the client stops sending its high layer, the SFU moves the viewer down the ladder, and audio FEC increases. Show a clear "your connection is unstable" hint.
⏰
Top-of-hour join storm

Millions of meetings start at 10:00. Join requests, ticket signing and ICE setup spike to ten times the average for three minutes.

Pre-scale signalling and placement on a schedule, cache meeting settings so joins do not hit the database, and spread clients' retries with jitter. Placement pre-assigns SFUs for scheduled meetings a few minutes early.
🎞️
A recording worker dies

The worker composing a two-hour board meeting crashes at minute 90.

Workers write raw streams to durable storage in short segments, so another worker resumes from the last segment. Users are told the recording is processing, not lost.
🌀
Reconnect storms make an outage worse

A brief network blip disconnects a hundred thousand clients, which all retry instantly and overload the signalling fleet as it recovers.

Exponential backoff with random jitter on every client, admission limits on signalling nodes, and a lightweight "resume" path that reuses the existing session instead of a full join.

09

How to run the interview

09

How to run the interview

1

Name the three planes in the first minute. Control, signalling and media have different latency, scale and failure needs. Saying so frames the whole interview.

2

Start from the latency budget. Break 250 ms into capture, encode, network, jitter buffer and decode. It explains why media servers must be close to people and why TCP is a fallback.

3

Explain the SFU properly. Say that it forwards packets without decoding, why that makes it cheap, and how simulcast lets each viewer get a different quality.

4

Describe graceful degradation step by step. A concrete ladder from full video down to audio only is one of the strongest answers you can give.

5

Do the bandwidth sum. Participants times per-viewer bitrate gives tens of terabits per second. That number justifies edge placement and careful layer selection.

6

Bring up NAT traversal. STUN, TURN and why some users must be relayed over 443 show that you have thought about real networks.

7

Avoid two classic traps. Do not route media through your REST servers, and do not reach for an MCU because it seems simpler.

10

Growing the design in stages

11

Growing the design in stages

Stage 1: a prototype for small teams
Peer-to-peer calls with one signalling server

Browsers connect directly with WebRTC, and a single WebSocket server exchanges session descriptions. Works well up to three or four people.

Stage 2: first paying customers
One SFU region and TURN fallback

Group calls move to an SFU, corporate users get TURN over 443, and a meetings database replaces in-memory rooms.

Stage 3: tens of thousands of meetings
Simulcast, the bandwidth ladder and recording

Senders publish three layers, receivers get layers by bandwidth and tile size, and recording runs on separate workers.

Stage 4: millions of participants worldwide
Edge locations and cascading

SFUs move to dozens of edges with a private backbone. Placement uses client probes, and global meetings cascade across edges.

Stage 5: the largest scale
End-to-end encryption, SVC codecs and webinars

AV1 with scalable coding cuts bandwidth, end-to-end encryption becomes an option, and webinars use a fan-out tree of SFUs. The original single signalling server is long retired.

Watch and read

Try next

Free to read · better with landed

Whiteboard this with landed

landed runs it as a live system design round on the whiteboard and grades your trade-offs.