Voice Chat Bandwidth on a Game Server: Opus vs PCM, Per-Slot Cost, and the 20/50/100 Player Math

A single player speaking on Opus at 32 kbit/s generates about 4 KB of payload per second — but at 100 concurrent players that same codec quietly consumes 6–12 Mbit/s of bidirectional bandwidth once packet headers, relay fan-out, and jitter buffers are counted. Voice is the part of a game server’s bandwidth budget that scales with the square of activity, not with slot count, and it is where most capacity plans go wrong.

Every figure below is derived from codec bitrate, 20 ms packetisation, RTP/UDP/IP headers, and the relay model, so each one is reproducible.

Opus vs PCM: What the Bitrate Actually Costs

Uncompressed PCM at 48 kHz, 16-bit mono is 768 kbit/s, and stereo doubles it. That is fine point-to-point and absurd for a relay fanning one speaker to 99 listeners, where a single voice would consume 76 Mbit/s of egress.

Opus in voice mode is transparent for speech around 24–32 kbit/s, good at 16 kbit/s, and artefacted at 8 kbit/s. Narrowband modes land at 8–12 kbit/s and degrade badly under background game audio.

Codec / modeBitratePer-speaker egress to 1 listenerQuality note
PCM 48k mono768 kbit/s768 kbit/sreference, no compression
Opus voice 48k32 kbit/s32 kbit/stransparent for speech
Opus voice 24k24 kbit/s24 kbit/sgood, slight sibilance
Opus narrowband8 kbit/s8 kbit/saudible artefacts

Opus is variable bitrate by design. A speaker averaging 24 kbit/s can burst to 40–60 kbit/s on a plosive, so capacity planning should use the configured cap plus 50% headroom rather than the average. If the encoder is not capped, the burst is whatever the complexity estimator decides that frame needs.

Packetisation Overhead Nobody Budgets

A 20 ms frame at 32 kbit/s carries 80 bytes of Opus payload. Add a 12-byte RTP header, 8 bytes of UDP, and 20 bytes of IPv4: 40 bytes of overhead on 80 bytes of payload, a 50% tax before any tunnel. With encapsulation, expect 60 bytes or more.

# egress bandwidth per listener for one speaker
gross_bps = (payload_bytes + 40) * 8 / 0.020   # 20 ms frames
# 32 kbit/s Opus  -> (80 + 40) * 8 / 0.02 = 48,000 bps
# 24 kbit/s Opus  -> (60 + 40) * 8 / 0.02 = 40,000 bps

So a 32 kbit/s stream costs 48 kbit/s on the wire. Over a 100 Mbit/s port that looks trivial; through a relay fanning out to every listener it multiplies fast. Frames also arrive every 20 ms regardless of whether anyone is mid-sentence, because comfort noise and DTX settings govern silence.

Discontinuous transmission saves roughly 40–60% on typical conversational traffic, but only if the encoder supports it at the source; a relay cannot invent silence it never received.

UDP vs TCP: Why Voice Cannot Use TCP

Voice belongs on UDP, and this is not a preference. TCP’s head-of-line blocking means one lost packet stalls every later packet until the retransmit arrives. On a 2% loss path that turns one 80-byte frame into 200–400 ms of added latency on the whole stream.

UDP drops the packet and moves on; a 20 ms Opus frame is concealed by the decoder from the previous frame’s spectrum. The right loss strategy is forward error correction (1–2 redundant frames), costing 20–30% extra bandwidth for direct resilience.

TCP suits the relay’s control channel — join, mute, codec change — where reliability matters and volume is negligible. Separate sockets let the control plane stay synchronous while the media plane degrades.

The Relay Fan-Out Problem

Two architectures give very different egress. A peer-to-peer mesh has every client send to every other, so each client’s upstream is (N-1) × 48 kbit/s — at 17 speakers, 768 kbit/s per client, which breaks consumer connections immediately.

Server relay sends each client one stream and receives one from each active speaker. Server ingress is then speakers × 48 kbit/s and egress is listeners × (per-mixed-stream cost). The server’s CPU does the mixing, and that mixing cost is the real constraint: mixing 10 active streams at 20 ms frames is 50 mix operations per second per listener.

PlayersConcurrent talkersRelay ingressRelay egress (48k)Total voice
2060.29 Mbit/s0.96 Mbit/s~1.25 Mbit/s
50150.72 Mbit/s2.40 Mbit/s~3.1 Mbit/s
100301.44 Mbit/s4.80 Mbit/s~6.2 Mbit/s

Those figures exclude overhead on the egress side, which is another 40 bytes per 20 ms packet per listener — 16 kbit/s each. At 100 players that adds 1.6 Mbit/s, pushing the realistic total to roughly 7.8 Mbit/s. This is the number to put in the capacity plan, not the 6.2 figure.

Jitter Buffer Headroom

The jitter buffer is deliberate delay that absorbs variance: no bandwidth cost, all of it paid in responsiveness. 60 ms covers typical internet variance; 200 ms survives a congested home uplink but feels like a satellite call. Most stacks default to 100–200 ms, which is too much for competitive play.

Adaptive buffers, which grow and shrink with observed variance, are the right choice. Size the ceiling from p99 jitter plus one frame interval: 45 ms jitter with 20 ms frames needs 80 ms, and anything more buys protection you pay for in perceived lag.

The buffer does not reduce bandwidth, only delivery timing, so a server provisioned exactly at the computed bitrate still sees bursts when a listener reconnects and requests catch-up frames.

Fitting Voice Into the Server’s Bandwidth Budget

Replication for 100 players at 60 Hz typically runs 25–40 Mbit/s egress, so 7.8 Mbit/s of voice is a 20–30% increase. That is fine on a 250 Mbit/s commit and is the component that breaks a 100 Mbit/s shared uplink also carrying updates, backups, and log shipping.

Treat voice as a separate budget line and ask the provider for a dedicated commit if it is a core feature of the game. Servers that also run a web map, an RCON panel, and a mod repository need the uplink commitment sized with headroom rather than to the replication figure alone, and the same profile should hold up against a 30-minute node acceptance test.

Practical Defaults

  • Codec: Opus, 48 kHz voice mode, capped at 24–32 kbit/s for competitive play.
  • Frame size: 20 ms. 10 ms doubles packet rate and header overhead; 60 ms adds perceptible delay.
  • Transport: UDP with 20–30% FEC, TCP only for the control channel.
  • Jitter buffer: adaptive, upper bound = p99 jitter + one frame interval, never above 120 ms for shooters.
  • Capacity: assume 30% of slots talk at once, engineer the uplink at 1.5× the computed total.

Measure actual codec output rather than trusting the configured cap: encoders overshoot and DTX behaviour varies by platform. A week of per-channel bitrate logging beats any table, including this one.

Leave a Reply