Zoom looks simple: click a link, see faces, talk. Behind that click is a system that moves tens of terabits of live audio and video a second, where a packet that arrives 300 ms late is as useless as one that never arrived. In March 2020, Zoom went from about 10 million to more than 200 million daily meeting participants in three months, as offices, schools and families moved online at once — a 300-student online lecture during lockdown, a company all-hands, a Diwali video call stitching together grandparents in Pune, an uncle in Dubai and cousins in Toronto. In this problem you design that service: how people find and join a meeting, how media flows between them with less delay than a phone call, how one weak 4G connection doesn’t ruin the call for everyone, and how meetings stretch across continents, grow to 1,000 viewers, get recorded and stay private.
Understand the problem
Most candidates spend their time on the parts that look like any web app — scheduling, accounts, a meetings table. Those are easy. The hard part is the media plane: real-time audio and video between people on very different networks, under a latency budget measured in tens of milliseconds, where the server’s outgoing bandwidth is the dominant cost. Say that early and steer your time there.
Functional requirements
- Users should be able to schedule a meeting and join it with a link or meeting ID, with an optional passcode and waiting room.
- Participants should be able to talk and see each other in real time — up to 100 people with audio and video in a meeting, or up to 1,000 receive-only attendees in a webinar.
- Participants should be able to share their screen.
- Participants should be able to chat in the meeting.
- Hosts should be able to record a meeting to the cloud.
Non-functional requirements
- Latency. One-way mouth-to-ear delay under 150 ms within a region. ITU-T G.114 finds that below 150 ms most applications feel “essentially transparent”, and treats 400 ms as the limit for network planning; a 10,000 km path comes to about 225 ms, which most users still find acceptable. Joining should take a second or two from click to hearing people.
- Loss and jitter. Home Wi-Fi and mobile networks lose and delay packets. Audio must stay intelligible through a few percent of loss and short bursts; video should degrade (lower resolution, lower frame rate) long before audio does.
- Bandwidth. Clients range from fibre to a phone on a moving train. Zoom’s published guidance is a useful anchor: about 60–80 kbps for audio, 1.0 Mbps up and 600 kbps down for “high quality” group video, 2.6 Mbps up and 1.8 Mbps down for 720p group calls, and 2.0 Mbps to receive a 25-tile gallery.
- Scale. Zoom reported more than 200 million daily meeting participants in March 2020, up from about 10 million in December 2019. That number counts participations, not people: one teacher in five classes counts five times. Design for 200M participant-joins a day.
- Availability. 99.99% for joining. Losing a media server should interrupt the affected meetings for a few seconds, not end them.
- Security. Media is always encrypted in transit; end-to-end encryption is available on request, with documented trade-offs.
- Consistency. The participant list and host controls (who is admitted, muted, made co-host) need one authoritative order per meeting. Media is the opposite: lossy by design, and never retried if it would arrive too late.
In the interview
Ask before you draw: “How big are meetings — four people or a thousand?”, “Interactive for everyone, or a few speakers and many viewers?”, “Do we need recording, phone dial-in, end-to-end encryption?” and “Are meetings global?” Size decides the forwarding strategy, the speaker-to-viewer ratio decides whether you need a webinar tier, recording and dial-in decide whether servers may see media at all, and geography decides whether you cascade servers across regions.
Out of scope
- Phone dial-in (PSTN). Telephony gateways that mix and transcode audio for phones; a different problem with its own vendors and regulations.
- Whiteboards and annotations. Collaborative drawing is closer to Google Docs than to media.
- AI summaries and live captions. Consumers of the media, built on the recording and transcription pipeline.
- Calendar integration and accounts. Standard web features with no real-time constraints.
The set-up
Plan the approach
Draw the two planes early. The control plane is a normal service-oriented backend: a meeting service, a database, and WebSocket signalling servers that hold each meeting’s state. The media plane is a fleet of media servers in many regions that forward packets. Deep dives then go where the problem is won: forwarding topology, adapting quality to each receiver, surviving loss, getting through firewalls, and scaling meetings up and across the world.
Core entities
- Meeting. ID (the 10–11 digit number people type), host, passcode hash, settings (waiting room, encryption mode, auto-record), schedule.
- Participant session. Who joined which meeting, with what role (host, co-host, panelist, attendee), on which media server, and their state (muted, camera on, sharing).
- Track. One media source from one participant: microphone audio, camera video or screen share. A video track may carry several encodings (simulcast layers), each with its own RTP stream identifier (SSRC).
- Media server assignment. Which SFU in which region hosts which participants of a meeting, and how those SFUs link to each other.
- Chat message. Meeting, sender, recipients (everyone or one person), text, sequence number.
- Recording. Meeting, status, the chunks written so far, the final files.
API
REST, for everything before the media starts.
POST /v1/meetings
Content-Type: application/json
{ "topic": "Diwali family call", "start": "2026-11-08T19:30:00+05:30",
"settings": { "waiting_room": true, "encryption": "enhanced", "auto_record": false } }
{ "meeting_id": "84219375560", "join_url": "https://meet.example.com/j/84219375560?pwd=Fq2...", "host_key": "..." }
POST /v1/meetings/84219375560/join
Content-Type: application/json
{ "display_name": "Asha", "passcode": "diwali26", "client": { "os": "android", "version": "6.2" } }
{
"participant_id": "p_31",
"signaling_url": "wss://sig-bom.meet.example.com/v1/m/84219375560",
"token": "eyJhbGciOi...",
"media": { "sfu": "sfu-bom-17.meet.example.com", "region": "ap-south-1" },
"ice_servers": [ { "urls": ["turns:turn-bom.meet.example.com:443?transport=tcp"], "username": "...", "credential": "..." } ]
}
Signalling, over one WebSocket per participant. The client announces what it can send and what it wants to see; the server pushes roster changes, speaker changes and chat:
{ "type": "publish", "tracks": [
{ "kind": "audio", "codec": "opus" },
{ "kind": "video", "source": "camera", "encodings": ["180p", "360p", "720p"] } ] }
{ "type": "subscribe", "layout": "gallery", "page": 1,
"tiles": [ { "participant": "p_12", "max_height": 360 }, { "participant": "p_07", "max_height": 180 } ] }
{ "type": "active_speaker", "participant": "p_12", "at": "19:42:07.310" }
{ "type": "chat", "to": "everyone", "seq": 214, "from": "p_31", "text": "Happy Diwali, Nani!" }
Media does not use this API at all. It flows as SRTP packets over UDP between the client and its SFU, with RTCP feedback (receiver reports, NACKs, keyframe requests, congestion-control feedback) alongside.
Back-of-envelope estimates
These numbers decide where media servers live, what limits them, and how big the recording problem is. (Method: back-of-envelope estimation.)
Concurrency. 200M participant-joins a day, each about 40 minutes: 200M × 40 = 8 billion participant-minutes a day. Spread over 1,440 minutes that averages 8B ÷ 1,440 ≈ 5.6M people in meetings at any moment, and roughly twice that in the working-hours peak, ≈ 11M. With about 5 people per meeting, that is 11M ÷ 5 ≈ 2.2M concurrent meetings.
Media bandwidth. Assume the average participant sends about 1 Mbps (many cameras are off or sending only small layers) and receives about 1.5 Mbps (Zoom’s guidance is 1.8 Mbps down for a 720p group call). At peak: 11M × 1 Mbps = 11 Tbps into the media servers and 11M × 1.5 Mbps = 16.5 Tbps out — close to 30 Tbps in total.
Media servers. An SFU’s limit is packets, not decoding: every packet is decrypted, has its header rewritten and is encrypted again for each receiver. Budget about 10 Gbps of egress per server: with roughly 1,200-byte packets, that is 10 Gbps ÷ (1,200 × 8 bits) ≈ 1M packets a second. Then 16.5 Tbps ÷ 10 Gbps = 1,650 servers, about 3,300 with 2× headroom, spread over 15–20 regions.
Signalling. 200M joins ÷ 86,400 s ≈ 2,300 joins/s on average, but meetings start on the hour and half-hour, so expect bursts around 10× that, ≈ 23k joins/s for a few minutes. Holding 11M WebSockets at about 50k per server needs about 11M ÷ 50k = 220 signalling servers. Roster, speaker and chat events are tiny next to media.
Recording. Meeting-minutes are 8B participant-minutes ÷ 5 = 1.6B a day. If 2% are recorded, that is 32M minutes, about 533k hours. A composite 720p recording at 1.5 Mbps is 1.5 Mbps × 3,600 s = 5,400 Mb = 675 MB an hour, so 533k × 675 MB ≈ 360 TB of new recordings a day, written by about 2% × 2.2M ≈ 44k recording bots at peak.
What the numbers decide: media is two orders of magnitude bigger than everything else and must stay on media servers close to users, never routed through application servers or one central region; server egress dominates, so per-receiver decisions (which layer, which speakers) are the biggest lever on cost; signalling is a normal real-time service; and recording is a storage and batch-processing problem bolted onto the side.
Tip
For video systems, count bits per second, not requests per second. A single 100-person meeting can push more bytes than a busy REST API — and every one of those bytes has a deadline.
High-level design
Build one requirement at a time. By the end of this section the design works for small meetings in one region.
Users should be able to schedule and join a meeting
Scheduling is plain CRUD on a meeting service backed by a meeting DB. Joining is where the planes meet: the meeting service checks the passcode and waiting room, an allocator picks a media server for this participant, and the client gets two addresses — a signalling WebSocket and an SFU.
The allocator’s rule is simple to start with: put the participant on a lightly loaded SFU in the region nearest to them, and if the meeting already has an SFU in that region, use the same one so the meeting’s streams stay on one machine. Meeting state — who is in, who is muted, who is admitted from the waiting room — is owned by one signalling server per meeting, the same single-owner idea as in Google Docs, so host controls are applied in one order.
Participants should be able to talk and see each other
Media cannot use the request-response tools of the rest of the system. It is a continuous stream of small packets, one every 20 ms for audio and dozens a second for video, and each has a deadline. That drives three choices:
- UDP, not TCP. TCP retransmits a lost packet and holds back everything behind it until the retransmission arrives — head-of-line blocking. For a file that is right; for a voice, a packet that arrives 200 ms late is worse than none. Over UDP, the application decides what is worth repairing (see TCP vs UDP).
- RTP and RTCP on top. RTP adds a sequence number (to spot loss and reorder), a timestamp (to play at the right time) and a stream identifier to each packet. RTCP carries the feedback: what was received, what was lost, and how much bandwidth is available. SRTP encrypts it, with keys agreed through a DTLS handshake.
- A forwarding server in the middle. Each client sends its media once to a Selective Forwarding Unit (SFU), which forwards copies to everyone else without decoding them. The first deep dive compares this with the alternatives.
Every millisecond on the way from Asha’s mouth to Ravi’s ear counts, and the budget fills up fast:
Participants should be able to share their screen
A screen share is just another video track with different settings. Text must stay sharp, so it is sent at full resolution but a low frame rate — a few frames a second for slides, more for video playback — and encoded in a mode tuned for screen content. A static slide compresses to almost nothing: Zoom budgets 50–75 kbps for screen sharing without a camera thumbnail. The cost arrives when the slide changes and a large keyframe is sent at once. Two rules follow: the screen share gets priority over camera video when bandwidth is short (people can live without your face but not without your slide), and receivers always get it at the largest size their window shows.
Participants should be able to chat in the meeting
Chat goes over the signalling WebSocket, not the media path. The meeting’s signalling owner gives each message a sequence number, fans it out to everyone (or to one person for a direct message), and appends it to a chat store if the meeting saves chat. Late joiners fetch history by sequence number. This is a small version of a group-chat system and borrows its patterns: one ordering point per conversation and idempotent delivery.
Hosts should be able to record a meeting
The cleanest recorder is a participant. When the host presses Record, the control plane starts a recording bot in the same region as the meeting’s SFU. It joins as a hidden participant, subscribes to the active speaker and any screen share just as a client would, decodes and composites them into one layout, encodes the result and uploads it in 10-second chunks to blob storage. When the meeting ends, a post-processing job stitches the chunks, transcodes them into playback formats and notifies the host.
Keeping recording out of the SFU matters: the SFU stays a dumb, fast forwarder that never decodes, and a crashed recorder can be restarted (it resumes from its last uploaded chunk) without touching the live call.
This works for a handful of people in one region on good networks. It does not yet say why an SFU rather than something else, how one SFU serves a fibre user and a 4G user from the same sender, what happens when packets go missing, how clients behind strict firewalls connect at all, or how a 1,000-person webinar spanning three continents holds together.
Deep dives
Which media topology: mesh, MCU or SFU?
Take a 10-person family call where every camera sends 1.5 Mbps. There are three ways to get everyone’s video to everyone else, and RFC 7667, which catalogues RTP topologies, describes all three.
Bad: full mesh. Every client sends its stream directly to every other client. Each one uploads 9 × 1.5 = 13.5 Mbps and downloads the same, and the call carries 10 × 9 = 90 streams. Home broadband and mobile uplinks are often a few Mbps, so the call collapses somewhere around four people, and every pair must also punch through two NATs. Mesh is excellent for exactly one case: a 1:1 call, where it costs the provider nothing and has the lowest possible delay.
Good: an MCU (media-mixing mixer). A server receives every stream, decodes them, tiles the video into one picture, mixes the audio, re-encodes and sends each participant a single stream. Clients upload and download 1.5 Mbps each — easy for weak devices and old room systems. But the server must decode 10 streams and encode up to 10 outputs (each person needs an audio mix without their own voice, so RFC 7667 notes N or N+1 mixes), which is the most expensive thing a server can do with video. A decode-compose-encode cycle and an extra jitter buffer add tens of milliseconds, re-encoding loses quality, the server chooses everyone’s layout, and end-to-end encryption is impossible because the server must see pixels.
Great: an SFU (selective forwarding unit). Each client uploads once; the SFU forwards packets to the others without decoding. It rewrites RTP sequence numbers for each outgoing stream, passes on keyframe and bitrate requests, and decides which streams and which quality each receiver gets. Uplink stays at one stream (a little more with simulcast); downlink is up to 9 streams, each sized to the tile it fills; server work is per packet — decrypt, rewrite a header, encrypt — not per pixel. Zoom’s own media servers, which it calls Multimedia Routers, relay and multiplex meeting streams and, according to its cryptography whitepaper, do not decrypt the data to route it. The catch is that forwarded streams grow as N × (N − 1), which the next deep dives tame.
| Full mesh | MCU (mixer) | SFU (forwarder) | |
|---|---|---|---|
| Client upload | 9 × 1.5 = 13.5 Mbps | 1.5 Mbps | 1.5 Mbps (≈ 2.15 with simulcast) |
| Client download | 13.5 Mbps | 1.5 Mbps, one composite | Up to 9 streams, each sized to its tile |
| Server work | None (a relay if NATs block) | Decode, composite, re-encode per receiver | Decrypt, rewrite headers, re-encrypt |
| Added delay | Lowest | Highest: a decode–encode cycle plus buffering | A few ms per hop |
| Who picks the layout | Each client | The server | Each client |
| End-to-end encryption | Natural | Impossible | Possible with frame encryption |
| Best for | 1:1 calls | Phones, legacy room systems, recordings | Group meetings — the default |
The Jitsi team measured the difference on real hardware: in a 30-participant conference, an SFU that forwarded video for 10 of the endpoints used 45% less CPU and 63% less bandwidth than one that forwarded everyone to everyone. Recommendation: SFU for every group meeting; direct peer-to-peer for 1:1 calls, moving to the SFU when a third person joins; and a mixer only at the edges where one combined stream is genuinely required — phone dial-in, recording, old room systems.
How does each receiver get the quality it can handle?
Asha sends from fibre in Pune. Ravi watches her full-screen on a laptop; Kabir sees her as one tile of a gallery on a tablet; Meera is on 4G on a moving train with about 300 kbps to spare. If Asha sends one 720p stream, the SFU cannot shrink it for Meera without decoding it — which would turn it back into an MCU.
Bad: one encoding for everyone. Size it for the weakest receiver and everyone gets 180p because of one train journey; size it for the strongest and Meera’s video freezes, her packets queue, and her audio starts breaking up too.
Good: simulcast. Asha’s client encodes the same camera three times at different sizes, say 180p at about 150 kbps, 360p at about 500 kbps and 720p at about 1.5 Mbps (an assumed ladder): 1.5 + 0.5 + 0.15 ≈ 2.15 Mbps of upload. Zoom’s own guidance is consistent with this pattern: 2.6 Mbps up but only 1.8 Mbps down for a 720p group call — you upload more than you download because you send more than one version. The SFU then forwards to each receiver the largest layer that fits both the tile and that receiver’s bandwidth. Switching to a different layer needs a keyframe on the new layer, because a decoder cannot start mid-stream, so the SFU requests one and switches when it arrives. You pay roughly 40% more upload than a single 720p stream, and the sender’s CPU encodes three times — so the SFU tells senders to pause layers nobody is watching — the Last N paper describes the SFU doing exactly this for streams no one receives.
Great, where the codec allows it: scalable video coding (SVC). One encoding carries layers: temporal (for example 7.5, 15 and 30 frames a second) and spatial (180p, 360p, 720p), each layer building on the ones below. The SFU simply drops the packets of layers a receiver does not need, so switching down is instant and needs no keyframe, and upload is lower than simulcast. You pay in codec and hardware support — VP9 and AV1 support SVC, while H.264’s scalable mode is rarely available in the hardware encoders of phones and laptops — and in decoder complexity. A common middle ground is simulcast for resolution with temporal layers inside each encoding, so the SFU can halve a stream’s frame rate on the fly.
Bandwidth estimation decides the layers. The SFU must know how much each receiver’s downlink can take, and each sender must know its uplink. The usual tool is Google Congestion Control (GCC), which combines two controllers. A loss-based one lowers the estimate when more than 10% of packets are lost, holds it between 2% and 10%, and raises it below 2%, over windows of about a second. A delay-based one watches whether packets arrive increasingly late — a sign that a queue is building at the bottleneck — and backs off before loss starts. With transport-wide congestion control feedback, the receiver reports the arrival time of every packet, so the sending side runs the estimator: the client for its uplink, the SFU for each receiver’s downlink.
The SFU then spends each receiver’s budget in priority order: audio first, screen share next, then video by importance. Meera’s estimate is 300 kbps: three speakers’ audio at about 40 kbps each is 120 kbps, the active speaker at 180p takes 150 kbps, and the remaining 30 kbps buys nothing more, so other tiles show avatars. Kabir, at 1.2 Mbps in a nine-tile gallery: 120 kbps of audio, the speaker at 360p for 500 kbps, and three more tiles at 180p for 450 kbps — 1,070 kbps in total — with the other five tiles paused. Before moving anyone up a layer, the SFU probes with a little extra traffic to confirm the bandwidth is really there; moving down happens immediately.
How do we keep audio and video smooth on lossy, jittery networks?
Packets get lost (Wi-Fi interference, a cell handover on the Mumbai–Pune expressway), arrive out of order, and arrive with varying delay — jitter. Each needs a different tool, and audio and video want different ones.
- A jitter buffer holds incoming packets briefly so they can be played at an even pace. Too small and late packets miss their slot; too large and every word arrives later. Make it adaptive: track recent jitter, size the buffer to cover most of it (often 20–80 ms for audio), and stretch or shrink playback imperceptibly when the network changes. When an audio packet misses its slot anyway, packet loss concealment synthesises a plausible 20 ms instead of a click.
- NACK (retransmission). The receiver sees a gap in sequence numbers and asks for that one packet. It only costs bandwidth for what was lost, but it costs a round trip, so it only works when the round trip is well inside the jitter buffer. This is where the SFU earns its place again: it keeps the last second or so of packets for every stream, so a receiver’s loss is repaired from the SFU over one short hop instead of from a sender who may be across an ocean.
- FEC (forward error correction). Send redundancy up front — the previous audio frame repeated inside the next packet, or parity packets for video — so the receiver can rebuild a lost packet with no round trip at all. The price is extra bandwidth all the time. When loss is steady, FEC is the lower-latency option; for audio, which is small, it is almost always worth it.
- Keyframe requests. If a video packet cannot be recovered, the decoder’s chain of reference frames breaks and the receiver asks for a keyframe. Keyframes are several times larger than normal frames, so the SFU must coalesce requests (50 receivers asking at once should produce one keyframe, not 50) and rate-limit them, or one bad connection makes the sender flood everyone.
- Degrade in order. Drop video frame rate first (temporal layers), then resolution, then turn video off; keep audio to the end.
| Tool | Repairs | Costs | Use it for |
|---|---|---|---|
| Jitter buffer | Varying delay, reordering | Added latency equal to its depth | Every stream, sized adaptively |
| NACK from the SFU’s cache | Isolated lost packets | One short round trip; bytes only for losses | Video, and audio on short paths |
| FEC or redundancy | Lost packets, with no round trip | Constant extra bandwidth | Audio; video on high-latency or steadily lossy paths |
| Keyframe request | A broken video decoder | A large burst from the sender | Last resort, coalesced and rate-limited |
| Packet loss concealment | Audio gaps that could not be repaired | Slight audio artefacts | Audio, always |
The rule of thumb: audio gets FEC, concealment and a small buffer; video gets NACK from the SFU, then a keyframe, plus temporal layers so it can slow down instead of freezing.
How do clients behind NATs and strict firewalls connect at all?
Almost every client sits behind something: a home router doing NAT, a mobile carrier sharing one public address among thousands of phones, or a corporate or campus firewall that allows little beyond web traffic. Two such clients cannot simply send UDP to each other.
The SFU design already removes the hardest case. SFUs run on public addresses, so a client only needs an outbound path to its SFU; true peer-to-peer traversal matters only for 1:1 calls. The tool for both is ICE (RFC 8445). Each side gathers candidate addresses — its local host address, its public server-reflexive address as seen by a STUN server, and a relayed address on a TURN server — pairs them up, runs connectivity checks on the pairs in priority order, and nominates the best pair that works. Against a public SFU, the client usually succeeds with its very first candidate.
When UDP is blocked, the client walks down a ladder. TURN (RFC 8656) can relay over TCP and over TLS precisely because, as the RFC explains, some firewalls block UDP entirely; the RFC also warns that relaying, while very likely to work, is costly for whoever runs the relay, which is why ICE tries direct paths first.
The fallbacks are a “works versus doesn’t work” trade, not a free win. Over TCP, one lost segment holds up everything behind it until it is retransmitted, TCP’s own congestion control fights the media’s, and jitter buffers must grow to hide the stalls — expect higher delay and occasional freezes. Watch the share of sessions on each rung: a rising TCP share usually means a new corporate firewall, not a bug.
Networks also change mid-call. When a phone moves from Wi-Fi to 4G, its address changes and the media path dies, but the signalling session can survive: the client performs an ICE restart — new candidates, new checks, same meeting — and media resumes in about a second without rejoining.
How do meetings span continents and grow to hundreds of people?
Across continents: cascade SFUs. The Diwali call has five people in India (three in Pune, two in Bengaluru) and four in Toronto.
Bad: one SFU for the whole meeting, wherever the first person joined. If that is Mumbai, each Toronto participant sends one stream across the ocean and pulls the eight others back: 4 + 4 × 8 = 36 streams crossing the ocean. Worse, two cousins in the same Toronto house hear each other via India, with two ocean crossings between them; and every lost packet on those long, public-internet paths needs a long round trip to repair.
Good: cascaded SFUs. Each participant connects to the nearest SFU — Mumbai or Toronto — and the two SFUs connect to each other, exchanging each stream once: 5 + 4 = 9 crossings. Toronto neighbours stay local, the long hop runs between data centres over a managed backbone, and loss is repaired hop by hop. Each SFU subscribes on its local receivers’ behalf to the largest layer any of them needs, so if nobody in Toronto watches Asha full-screen, only her 180p crosses the ocean. You pay with more moving parts: a mesh or tree of SFUs per meeting, bandwidth estimation on the links between them, a few extra milliseconds per hop, and a new failure mode where a broken cascade link splits the meeting until it is rebuilt.
Hundreds of people: forward less. A 100-person all-hands breaks the SFU’s arithmetic, because forwarded streams grow as N × (N − 1). Sending everyone every other camera even at 180p is 100 × 99 × 0.15 Mbps ≈ 1,485 Mbps for one meeting, and nobody can look at 99 faces anyway.
- Last-N video. Forward video only for the N most relevant people per receiver — recent speakers, pinned people, and the gallery page on screen — and pause senders nobody is receiving. The Jitsi paper that named the scheme shows the SFU then sends K × N streams instead of K × (K − 1). With a 25-tile page at about 80 kbps a tile (Zoom’s guidance of 2.0 Mbps to receive 25 tiles works out to 2,000 ÷ 25 = 80 kbps each), the meeting costs 100 × 2.0 Mbps = 200 Mbps.
- Loudest-N audio. Audio from everyone is 100 × 99 × 40 kbps ≈ 396 Mbps, mostly silence. Each sender stamps its audio level into an RTP header extension, so the SFU can forward only the three loudest without decoding anything: 100 × 3 × 40 kbps = 12 Mbps.
- Stable speaker detection. Choosing the active speaker from levels over a window, not instant by instant, stops the big tile flicking between people at every cough. When someone new becomes the speaker, the SFU asks their sender for a keyframe once and forwards it to everyone, rather than waiting for every receiver to ask.
Webinars: separate speakers from audience. A webinar has a few panelists who publish and up to 1,000 attendees who only receive (the size Zoom’s whitepaper gives as a meeting’s ceiling). Attendees send nothing, so they need no uplink budget and no last-N on the sending side; each receives the active speaker plus any screen share, about 1.8 Mbps, so 1,000 attendees need about 1.8 Gbps. Spread them across SFUs in each region, fed through the same cascade: the panelists’ SFU is the root of a distribution tree, regional SFUs are its branches. Promoting an attendee to panelist just means letting them publish. Beyond a few thousand viewers, interactivity stops mattering, and handing the stream to a live-streaming pipeline (HLS through a CDN) is cheaper at the price of several seconds of delay.
How do recording and end-to-end encryption fit together?
Start with what encryption looks like by default. Media is encrypted hop by hop with SRTP, keyed through DTLS, between each client and its SFU. That protects packets on the public internet, but the SFU terminates the encryption to rewrite headers, so the provider could see media. Zoom’s default, which it calls enhanced encryption, works this way at the key level: the server generates a 256-bit per-meeting key, media is encrypted with AES-256-GCM using keys derived from it, and the media routers forward without decrypting — but because Zoom’s servers hold the key, its connector servers can decrypt and mix streams for phone and SIP participants, and cloud recording can record the decrypted meeting.
Recording under the default. The recording bot from the high-level design is a participant with the key. It joins through an SFU in the meeting’s region, subscribes to the active speaker and any screen share, composites and encodes them, and uploads numbered 10-second chunks to blob storage. Chunks are idempotent by meeting and number, so a crashed bot is replaced and resumes from the last chunk written; the meeting never notices. Post-processing stitches, transcodes and notifies the host, and lifecycle rules move recordings to colder storage after a month — at about 360 TB of new recordings a day, retention policy is the cost model.
End-to-end encryption moves the key to the clients. In Zoom’s design, one participant’s client — the meeting “leader”, usually the host’s — generates the meeting key and sends it to each participant encrypted to that participant’s public key, over the signalling channel; servers only relay. The leader generates a fresh key whenever someone joins or leaves (and every five minutes regardless), so a newcomer cannot read what was said before and someone who left cannot read what comes after. Media frames are encrypted before they are split into packets, which is exactly the job SFrame (RFC 9605) standardises: two layers, hop-by-hop SRTP to the SFU and end-to-end encryption of each frame inside it, so the SFU still reads what it needs to forward — sequence numbers, layer identifiers, audio levels — but never the picture or the voice.
What end-to-end encryption breaks, per Zoom’s own documentation of its mode: cloud recording cannot be enabled, and participants cannot join by phone, from a web browser or from legacy room systems — anything that needs a server to see media is gone. The same applies to server-side transcription and AI features, server-side composition for weak devices, and abuse review. Participants can still record locally, because their own client holds the key. And the SFU still learns plenty from metadata: who speaks when, how loudly, and how much. Recommendation: the server-keyed mode by default, because recording and dial-in are what most meetings need; end-to-end encryption as a per-meeting option, with the trade-offs shown in the UI when the host turns it on.
The final design
The control plane admits people and tells the media plane what to do; the media plane moves every byte of audio and video and never waits on the control plane.
Follow the Diwali call from link to recording:
- Join. Asha opens the link; the meeting service checks the passcode and waiting room against the meeting DB.
- Place. The allocator picks the least-loaded SFU in the region nearest Asha — reusing the meeting’s SFU there if it already has one — and returns its address with a short-lived token.
- Signal. Asha’s client opens a WebSocket to the signalling server that owns the meeting. It publishes her tracks, subscribes to the tiles she can see, and receives the roster, speaker changes and chat; signalling tells the SFU which transports and layers to set up.
- Media. Her client completes ICE and DTLS with the SFU and sends audio plus three simulcast layers over UDP. The SFU forwards to each receiver the layers its bandwidth estimate and tile size allow, repairs losses from its packet cache, and forwards only the last few speakers’ video and the loudest three voices.
- Fallback. If her network blocks UDP, the same media goes through a TURN relay over TCP or TLS on port 443, at some cost in delay.
- Cascade. The Toronto cousins connect to an SFU in Toronto; the two SFUs exchange each stream once over the backbone.
- Record. When the host presses Record, a recording bot joins through the SFU, composites the call and writes 10-second chunks to blob storage for post-processing.
Check it against the requirements. Within a region, mouth-to-ear delay is about 140 ms, inside G.114’s 150 ms; across continents about 225 ms, still acceptable. Loss is repaired on the shortest possible hop, audio is protected first, and video degrades before it freezes. Each client uploads once, whatever the meeting size, and each receiver gets only what fits its network and screen. The SFU fleet — about 3,300 servers moving 16.5 Tbps out at peak — scales by adding servers per region, because meetings are independent; signalling and joins are ordinary web-scale work. An SFU failure costs its meetings a few seconds while clients reconnect elsewhere, and end-to-end encryption is available where its trade-offs are acceptable.
What interviewers look for by level
| Area | Mid-level | Senior | Staff |
|---|---|---|---|
| Requirements | Join, audio, video, chat | Latency budget near 150 ms, bandwidth ranges, meeting sizes | Separates participations from users; lets meeting size and speaker ratio pick the architecture |
| Topology | “Use WebRTC peer to peer” | SFU over mesh and MCU, with the upload arithmetic | Knows where an MCU still belongs (phones, recording, room systems) and the N × (N − 1) egress problem |
| Adaptation | One bitrate for everyone | Simulcast, layer choice per receiver, keyframes on switch | SVC trade-offs, GCC with transport-wide feedback, pausing unwatched layers, probing before upgrades |
| Bad networks | “Retransmit lost packets” | Jitter buffer, NACK versus FEC | SFU packet cache, coalesced keyframe requests, audio-first degradation order |
| Connectivity | Assumes UDP works | ICE, STUN, TURN | The ladder down to TLS on 443, the cost of TCP for media, ICE restarts on network change |
| Scale and geography | One big server | SFUs per region | Cascading, last-N and loudest-N, webinar trees, the hand-off to live streaming |
| Security | “Use HTTPS” | SRTP with DTLS keys | Frame-level end-to-end encryption, key rotation on join and leave, and the features it disables |
Follow-up questions
What if an SFU crashes mid-meeting?
Its participants’ media stops, but their signalling WebSockets — on different servers — do not. Signalling notices through missed heartbeats and the clients’ own reports within a couple of seconds, asks the allocator for a healthy SFU in the same region, and tells each affected client to ICE-restart toward it; senders republish their tracks, receivers resubscribe, and the SFU requests fresh keyframes. Expect a few seconds of frozen video and silence, not a dropped meeting. Spreading a large meeting’s participants across two SFUs in a region halves the blast radius at the cost of an intra-region cascade.
What if we need breakout rooms?
A breakout room is a small meeting whose participants already have media connections. Keep them on the same SFU and change only subscriptions: the signalling owner moves Asha from the main room’s forwarding group to “Room 3”, and the SFU starts forwarding her streams to the people in Room 3 instead. No new ICE, no new DTLS, so moving 300 students into 60 rooms takes a second, not a minute. The host keeps a control channel to every room for broadcasts and timers.
What if a webinar needs 100,000 viewers?
Interactive delivery stops being worth its cost long before that. Keep panelists on SFUs, and have one recording-bot-like participant composite the webinar and feed a live-streaming encoder that produces HLS or DASH segments for a CDN. Viewers then get ordinary video over HTTP with several seconds of delay, and the provider pays CDN rates instead of SFU egress. Questions travel over a chat or Q&A channel, and a viewer promoted to speak is moved onto an SFU.
What if we must support phone dial-in later?
Phones speak PSTN or SIP, cannot decode several streams and cannot do frame-level encryption, so they need a mixer at the edge: a connector server that joins the meeting like a participant, decodes the loudest speakers’ audio, mixes it and sends one stream to the phone network, and does the reverse for the caller’s voice. That is an MCU for audio only, which is cheap. It needs the meeting key, which is why Zoom’s end-to-end mode disallows dial-in.
What if a participant’s network drops for five seconds?
Keep their place, not their packets. The client keeps its signalling session and retries media with an ICE restart; meanwhile the SFU marks the participant’s streams inactive and shows others their avatar, and does not forward stale packets when they reconnect. Audio comes back first, video on the next keyframe. If the outage lasts longer than about a minute, signalling marks them as having left so the roster stays honest.
How to say it in the interview
“I’ll design video meetings for about 200 million participant-joins a day, up to 100 interactive people per meeting and 1,000-viewer webinars, with mouth-to-ear delay under 150 milliseconds in a region.
I split it into two planes. The control plane — a meeting service, a database, an allocator and WebSocket signalling servers, one owner per meeting — handles joining, the roster, host controls and chat. The media plane is RTP over UDP through Selective Forwarding Units near the users, because a retransmitted packet that arrives 200 milliseconds late is useless.
I pick an SFU over a mesh, where ten people would each need 13.5 megabits of upload, and over an MCU, which decodes and re-encodes everything and adds delay. Each client uploads audio and three simulcast layers once; the SFU forwards each receiver the layer its bandwidth estimate and tile size allow, using GCC with transport-wide feedback, and pauses layers nobody watches. Jitter buffers absorb delay variation; the SFU repairs losses from a packet cache with NACKs, audio uses FEC, and keyframe requests are coalesced. ICE gets clients through NATs, falling back to TURN over TCP or TLS on 443.
At peak that’s around 11 million people and 16 terabits a second out of the SFU fleet — a few thousand servers — so cost comes down to forwarding less. Big meetings forward only the last few speakers’ video and the three loudest voices, which takes a 100-person meeting from about 1.5 gigabits to 200 megabits. Global meetings cascade SFUs so each stream crosses an ocean once.
Recording is a hidden bot participant writing chunks to blob storage. End-to-end encryption encrypts frames with keys held by a leader client, so the SFU routes on headers but can’t read media — which means no cloud recording or dial-in in that mode.”
Concepts used in this design
- TCP vs UDP — why media avoids head-of-line blocking and handles loss itself.
- Latency vs throughput vs bandwidth — the 150 ms budget and the megabits behind it.
- Real-time connections: long polling, SSE and WebSockets — the signalling channel.
- Peer-to-peer architecture — mesh for 1:1 calls, and why it stops there.
- Load balancing: L4 vs L7 — placing UDP media sessions on SFUs, not round-robin.
- Multi-region and active-active — SFUs near users and cascades between regions.
- Content delivery network — handing very large audiences to live streaming.
- Backpressure and load shedding — degrading video before audio when a link is congested.
- Heartbeats — detecting failed SFUs and dropped participants.
- Encryption and key management — hop-by-hop SRTP versus end-to-end frame keys.
- Blob storage — recording chunks and their lifecycle.
- Long-running jobs — post-processing recordings after the meeting.
- Design Google Docs — the same single-owner idea for meeting state, applied to documents.
References and further reading
- RFC 7667: RTP Topologiesrfc-editor.orgMesh, media-mixing mixers that decode N streams and produce N or N+1 mixes, and the Selective Forwarding Middlebox that rewrites RTP headers and relays keyframe requests.
- RFC 8445: Interactive Connectivity Establishment (ICE)rfc-editor.orgHost, server-reflexive and relayed candidates, connectivity checks on candidate pairs, and nomination of the pair to use.
- RFC 8656: Traversal Using Relays around NAT (TURN)rfc-editor.orgRelaying works almost always but is costly for the provider, so ICE uses it last; TCP and TLS transports exist because some firewalls block UDP entirely.
- RFC 9605: Secure Frame (SFrame)rfc-editor.orgEnd-to-end encryption of whole media frames so SFUs can still read the metadata they need, layered under hop-by-hop SRTP.
- ITU-T Recommendation G.114: One-way transmission timeitu.intUnder 150 ms mouth-to-ear is essentially transparent, 400 ms is the planning limit, and a 10,000 km VoIP path is about 225 ms.
- WebRTC for the Curious: Media Communicationwebrtcforthecurious.comNACK versus FEC, Google Congestion Control’s loss thresholds (2% and 10%) and delay-based controller, and transport-wide congestion control feedback.
- Last N: Relevance-Based Selectivity for Forwarding Video in Multimedia Conferences (Grozev, Marinov, Singh, Ivov, NOSSDAV 2015)jitsi.orgForwarding only the last N dominant speakers: K×N instead of K×(K−1) streams, pausing unwatched senders, and 45% less CPU and 63% less bandwidth in a 30-person test.
- Zoom Cryptography Whitepaper (Zoom, GitHub)github.comMultimedia Router servers, up to 1,000 participants per meeting, AES-256-GCM per-meeting keys, and which features end-to-end encryption disables.
- Zoom system requirements: bandwidth (Zoom Support)support.zoom.comRecommended bandwidth: 2.6 / 1.8 Mbps up/down for 720p group calls, 2.0 Mbps to receive a 25-tile gallery, 60–80 kbps for audio, 50–75 kbps for screen sharing.
- A Message to Our Users (Zoom, April 2020)zoom.comDaily meeting participants grew from about 10 million in December 2019 to more than 200 million in March 2020.