Voice chat is Discord's oldest core differentiator, and it operates under constraints that are almost the opposite of the rest of the product: where message delivery can tolerate a few hundred milliseconds of delay without anyone noticing, voice audio becomes noticeably degraded with latency budgets measured in tens of milliseconds. That combination — extremely tight latency requirements, at the scale of millions of concurrent voice sessions, across users with wildly varying network quality — shaped Discord's voice infrastructure around a fundamentally different architecture than its text and presence systems.

Why a selective forwarding unit instead of a full mesh or a mixer

For a group voice call, there are two classic architectural options, and Discord's engineers chose neither in its pure form. A full mesh, where every participant sends audio directly to every other participant, doesn't scale past a handful of people because each client's upload bandwidth requirement grows linearly with the number of other participants. A centralized mixer, where a server decodes every participant's audio, mixes it into one combined stream, and re-encodes it for each listener, scales participant count better but costs significant server-side CPU for decode-mix-encode on every channel, and it also removes each listener's ability to make their own choices about whose audio matters (like muting one noisy participant locally).

Discord instead built its voice infrastructure around the selective forwarding unit (SFU) model: each participant uploads their audio stream once to a Discord voice server, and the SFU forwards (without decoding or re-encoding) each participant's stream to every other participant who needs it. This keeps server-side CPU cost low — forwarding packets is far cheaper than transcoding audio — while keeping each client's upload bandwidth bounded to roughly one stream's worth, regardless of how many other people are in the call.

text
participant A --upload--> SFU --forward--> participants B, C, D
participant B --upload--> SFU --forward--> participants A, C, D

UDP, not TCP, and why that trade-off is deliberate

Discord's voice transport runs over UDP rather than TCP, accepting the possibility of packet loss in exchange for avoiding TCP's head-of-line blocking and retransmission delays, which would otherwise stall an entire audio stream waiting for one lost packet to be resent — exactly the wrong trade-off for real-time audio, where a single dropped packet's audio gap is far less disruptive than the delay of waiting for its retransmission. This is the same fundamental trade-off that underlies most real-time media protocols (like WebRTC's media transport), and it reflects a broader principle in real-time systems: for perishable, time-sensitive data, recency beats completeness.

Placing voice servers close to where people actually are

Because voice latency is so sensitive to physical network distance, Discord operates voice servers distributed across many regions globally and routes each user's client to a nearby server rather than a single centralized location, minimizing the round-trip time between a speaker and the SFU handling their channel. For calls with participants spread across different regions, Discord's infrastructure has to make a judgment call about which region's server should host the SFU for that call, generally optimizing to minimize the worst-case latency across all participants rather than simply defaulting to whichever region the call's creator happens to be in.

What you can borrow

  • Match your media/data routing architecture to the actual cost structure: forwarding is cheap, transcoding is expensive — an SFU-style pass-through beats a mixer whenever you don't strictly need server-side mixing.
  • For real-time, perishable data, prefer UDP-style "best effort, keep moving" transport over TCP-style "guaranteed, possibly delayed" delivery — a stale retransmit is often worse than a dropped packet.
  • Route users to infrastructure by physical proximity when latency is the binding constraint, not just by load or convenience.
  • When multiple valid architectures exist (mesh, mixer, SFU), the deciding factor is usually which cost you can least afford to pay at your target scale — bandwidth, CPU, or flexibility — not which is conceptually simplest.