Best pratices for livekit prod

Hello everyone,

I’m looking for best practices and recommendations for deploying a self-hosted (on-premises) LiveKit server.

My target is to support around 1,500 participants in a single room. My available network bandwidth is 1 Gbps.

The typical usage scenario is:

  • One presenter shares their screen, camera, and microphone.

  • Students join as viewers with their microphones and cameras disabled (listen-only mode).

  • The session is also recorded using LiveKit Egress.

My current server configuration is as follows:

( vCPU 16, RAM 32GB, storage 500GB and MiniO, Ubuntu 22.04, LiveKit Server 1.13)

I would appreciate your advice on the following points:

  • Is a single LiveKit server sufficient for this scenario, or would you recommend a clustered deployment?

  • What are the recommended LiveKit settings for this type of webinar?

  • Are there any specific optimizations for handling 1,500 viewers with only one active publisher?

  • What are the best practices for LiveKit Egress recording in this context?

  • Are there any bottlenecks or limitations I should anticipate, particularly with a 1 Gbps network connection?

  • If anyone has successfully deployed a similar on-premises setup, I’d be grateful if you could share your experience, architecture, or performance metrics.

Thank you in advance for your feedback and recommendations!
#####################
cat /opt/livekit/livekit-server.yaml
port: 7880

redis:
address: 127.0.0.1:6379
password: “MyPassword”

keys:
AAAAAAA: BBBBBBBBBBBBBBBBBBBBBB

rtc:
port_range_start: 40000
port_range_end: 60000
tcp_port: 7881
node_ip: mypublic-ip
use_external_ip: false
interfaces:
includes:

  • ens160

allow_tcp_fallback: false
use_mdns: false
packet_buffer_size_video: 1500
packet_buffer_size_audio: 500
batch_io:
batch_size: 128
max_flush_interval: 2ms
pli_throttle:
low_quality: 1s
mid_quality: 1.5s
high_quality: 2s
congestion_control:
enabled: true
allow_pause: true

stun_servers:

  • myapp-turndotexampledotcom:3478
  • myapp-turndotexampledotcom:443

turn_servers:

  • host: myapp-turndotexampledotcom
    port: 443
    protocol: udp
    username: XXXX
    credential: “XXXXXXM3AoakMMOnpp7MIVd8aj8”

  • host: myapp-turndotexampledotcom
    port: 443
    protocol: tls
    username: XXXX
    credential: “XXXXXXXXXXMMOnpp7MIVd8aj8”

turn:

enabled: false
udp_port: 443

room:
max_participants: 10000
empty_timeout: 300
departure_timeout: 20
enable_remote_unmute: true
enabled_codecs:

  • mime: audio/opus
  • mime: video/vp8
  • mime: video/h264

limit:
num_tracks: -1
bytes_per_sec: 1_000_000_000

logging:
level: warn
pion_level: error
json: true
sample: true

ingress:
rtmp_base_url: rtmps://myapp-rtc.example.com:1936/live
whip_base_url: https-//myapp-rtcdotexampledotcom/whip

webhook:
api_key: APIiRdMAsmvNobg
urls:

prometheus:
port: 6789

If the students are watching, why not stream it to YouTube? LiveKit includes an Egress service that records or renders a room and broadcasts it via RTMP. You provide your YouTube Live RTMP URL and stream key to the LiveKit Egress API, and LiveKit handles pushing the live feed directly to YouTube.
It means you’re doing one stream only.

Or using a passive viewers’ CDN.

If viewers just need to watch and can tolerate a few seconds of lag, don’t use WebRTC for everyone. Use LiveKit Egress to output HLS files to object storage like S3, then drop Cloudflare or CloudFront in front of it. LiveKit does one encode job, and the CDN handles the heavy lifting.

or for interactive viewers a WebRTC SFU Cluster.

If sub-second interaction is non-negotiable, HTTP CDNs won’t work. LiveKit handles high volume here by clustering its SFUs. The host stream hits a primary node, and LiveKit fans it out across edge nodes to stream directly to viewers.

The single most important thing to decide first is whether your audience actually needs sub-second interactivity, because an HLS CDN setup will cost a fraction of the price and spare you major infrastructure headaches.

Thank you for your detailed response.

In our use case, the audience is not completely passive, so HLS or YouTube Live alone would not meet our requirements.

During a typical session, the instructor shares their screen, camera, and microphone. Students normally join in listen-only mode, but they can raise their hand. When the instructor grants permission, a student can temporarily enable their microphone to ask or answer a question, and in some cases even share their screen. Once the interaction is over, the student is removed from the stage and returns to listen-only mode.

So we need real-time interaction with sub-second latency, which is why we chose LiveKit.

We also performed load testing with lk load on a local 10 Gbps network and were able to reach approximately 8,000 participants in a single room. The limiting factor in our production environment is currently our 1 Gbps Internet connection, which is why we intentionally cap our rooms at around 1,000 participants.

At this stage, my main question is not whether LiveKit can scale, but whether our current LiveKit deployment and configuration follow best practices for this type of workload.

I’m particularly interested in recommendations regarding:

  • LiveKit server configuration and tuning for large webinar rooms.

  • Whether our SFU configuration is appropriate or could be optimized.

  • Network and bandwidth optimization.

  • Any settings that could improve scalability, reliability, or media quality.

  • Whether anyone has experience running a similar on-premises deployment with around 1,000 concurrent interactive participants.

I’d really appreciate any feedback or suggestions from people who have deployed LiveKit at this scale.