How to size self-hosted LiveKit for 200 concurrent classrooms × 50 participants (10,000 total) — what hardware/config do I need?

Hi everyone,

I’m running self-hosted LiveKit (Docker Compose today, planning a multi-node cluster) for a university live-classroom platform. I need to plan hardware and configuration for this specific target, and I’d like a sanity check from people who’ve run LiveKit at this scale.

My target, in plain terms

  • 200 classrooms running at the same time
  • 50 participants in each classroom (1 instructor + 49 students) → 10,000 people online at once, total
  • In each classroom, at any moment: 1 person sharing their screen, and 1–3 people with their microphone active — everyone else is just watching/listening (camera mostly on, mic muted)

I want to know: how many LiveKit nodes do I need, how big should each one be, and what should I configure differently to reliably support this?

What I’ve already measured myself (so you don’t have to guess at my baseline)

On a single 8-core / 7.8 GB host, I ran a load test shaped like real classrooms (many separate ~40-person rooms running at once, not one giant room):

  • Clean, no errors: 20 rooms × 40 people = 800 people at once
  • Starts degrading: 40 rooms × 40 people = 1,600 people at once
  • Fails hard: 60 rooms × 40 people = 2,400 people at once

Importantly, CPU and RAM were NOT maxed out even when it failed (CPU peaked around 60-68%, RAM even less). The failures were all connection-related — errors like could not establish signal connection and TURN Fail to refresh permissions, happening right when a burst of participants tried to join many rooms at once. So the bottleneck looked like connection/TURN handshake timing under a joining burst, not raw compute.

Caveat I want to be upfront about: this test’s load-generator ran on the same machine as the LiveKit server, so some of that measured strain was the test tool competing for CPU, not purely the server. I haven’t yet re-tested from a second machine to get a “clean” number — so treat my 800/1,600/2,400 figures as a reasonable but not fully isolated estimate.

Also important: this test only used audio (no video, no screen share). My real classrooms have video tiles and screen sharing, which cost more bandwidth than audio-only — so my current numbers likely overestimate how many people fit per node once real video is added.

What I’d love help with

  1. Is there a rule of thumb, or a formula, LiveKit itself recommends for “how many rooms of size N, with 1 screen-share + a few active mics, fit on one node”? I haven’t found an official sizing guide, only general docs.
  2. Since my bottleneck was connection/TURN handshake timing during a burst of joins, not CPU — what actually fixes that at scale? More nodes alone won’t help if, say, 200 classes all start at 9am and hit one node’s TURN server in the same few seconds. Is this a matter of a dedicated TURN server pool, larger UDP port ranges, OS-level tuning, or something else?
  3. Does anyone have real production numbers for self-hosted (not LiveKit Cloud) multi-node clusters running 5,000–10,000 concurrent participants — how many nodes, what hardware, how rooms are distributed?
  4. Any config recommendations specific to my case: Redis setup for multi-node, whether to give TURN its own dedicated subdomain/node once I have multiple servers, and simulcast/dynacast settings that matter for screen-share tracks specifically?
  5. Is there a known bandwidth cost per screen-share track and per active-audio participant I could use to convert my audio-only numbers into a more accurate video+screen-share estimate, instead of me guessing?

Happy to share my full config (livekit.yaml, Docker Compose setup) and raw load-test logs if that helps anyone give a more precise answer.

Thanks a lot!