LiveKit Load Tester CLI (Customized)
The tool is designed to simulate heavy traffic (publishers and subscribers) on a LiveKit server to benchmark CPU, Bandwidth, and connection stability.
It features automated reporting, generating PDF and CSV analysis using local Netdata metrics upon test completion.
Installation
Prerequisites
- Go – Ensure Go is installed on your machine.
- Git LFS – Required to pull large video assets used for testing.
- Netdata – A Netdata instance must be running at
http://localhost:19999to fetch CPU metrics.
Step-by-Step Install
Clone the repository and initialize Git LFS:
git clone git@github.com:Qubital/livekit-cli-sq.git
cd livekit-cli-sq
git lfs install
git lfs pull
Build and install the binary:
make install
The binary will be placed in your Go bin path. Verify installation:
~/go/bin/lk --version
Configuration
Server Setup
Tests are typically run against LiveKit Cloud or a dedicated self-hosted instance.
- Log in to the LiveKit Cloud Dashboard.
- Navigate to Settings > Keys to retrieve your API Key and API Secret.
- Ensure the server WebSocket URL is known (e.g.
wss://your-project.livekit.cloud).
Netdata Setup
Tests were mainly conducted on our Hetzner VM to benchmark the 2-CPU machine. To fetch data, at the end of each test, the CLI attempts to connect to:
http://localhost:19999
to download CPU reports.
-
Local Test: Ensure Netdata is installed:
sudo apt install netdata -
Remote Test: If testing a remote server, forward the Netdata port locally via SSH before running the test:
ssh -L 19999:localhost:19999 user@your-server-ip
CLI Command Reference
Base command:
~/go/bin/lk perf load-test [flags]
Essential Connection Flags
| Flag | Description | Example |
|---|---|---|
--url | WebSocket URL of the LiveKit server | wss://project.livekit.cloud |
--api-key | LiveKit API Key | APIxxxxxxxx |
--api-secret | LiveKit API Secret | Secretxxxxxxxx |
--room | Target room name | load_test_room_01 |
--duration | Test duration (s, m or h) | 5m |
Participant Configuration
| Flag | Description |
|---|---|
--video-publishers | Participants publishing video only |
--audio-publishers | Participants publishing audio only |
--subscribers | Participants that only subscribe (passive viewers) |
--num-per-second | Ramp-up rate (connections per second). Recommendation: keep low (2–5) to avoid saturating client CPU before the server |
Video Stream Customization (Publisher)
These flags control what is sent to the server.
--video-codec
h264(Recommended): Lightest on client CPU. Enables higher bandwidth testing.vp9: Heavy on client CPU. Useful for testing transcoding limits.
--source-video-name
Ensure there is a file named master_name_1080p.mp4 inside /pkg/provider/resources. Use name (without the master_ prefix and resolution) as the value for this flag.
--video-gen-layers
Defines the Simulcast layers generated by FFmpeg.
- Format:
codec,WxH,kbps,fps;(semicolon-separated) - Example:
vp9,320x180,100k,30;vp9,640x360,350k,30;vp9,1280x720,550k,30
Layout & Subscription Logic (Subscriber)
These flags control what is received from the server and are critical for stressing specific SFU forwarding paths.
--layout
Determines which video layer subscribers will request.
| Layout | Behavior | Typical Bitrate |
|---|---|---|
all-high | Force High layer (720p / 1080p) | ~550 kbps – 1.5 Mbps |
all-medium | Force Medium layer (360p / 540p) | ~350 kbps |
all-low | Force Low layer (180p) | ~100 kbps |
speaker | Active Speaker simulation (1 High, rest Low) | Variable |
3x3 | Grid layout (forces Medium) | ~350 kbps |
Understanding the Output
After completion the CLI generates a timestamped folder inside:
./results/
Pressing Ctrl+C kills the process and does not save any files.
1. PDF Report
File: REPORT_CPU_SUMMARY.pdf
This is the primary deliverable. It aggregates Netdata metrics matching the exact duration of the test.
Key Metrics
-
Total Load
< 70%→ Safe70–85%→ Warning (jitter likely)> 85%→ Critical (packet loss and disconnects expected)
-
System + SoftIRQ
- Represents network overhead
- High values (>40%) with low User CPU indicate the server is packet-bound (PPS limit), not CPU-bound
-
Other
- Includes Steal Time
- High values indicate host-level contention on cloud infrastructure
2. Subscriber Summary (Terminal Output)
Printed in the terminal at the end of the test.
-
Bitrate Validation
- Ensure the observed bitrate matches the requested layout.
- For example, if you request
all-medium(350 kbps) but only see ~150 kbps, this may indicate that the server is overloaded and unable to deliver the requested layer, or that there is a client-side CPU bottleneck.
-
Total Packet Loss
< 0.5%→ Excellent0.5–2.0%→ Congestion control active (quality drops)> 5.0%→ Severe failure
Standard Test Scenarios
Scenario A – More Publisher than Subscribers
Strategy: H.264 + request high/low resolutions.
~/go/bin/lk perf load-test \
--url wss://project.livekit.cloud \
--api-key KEY --api-secret SECRET \
--room TEST_THROUGHPUT \
--duration 3m \
--video-codec h264 \
--video-gen-layers="h264,320x180,150k,20;h264,320x180,350k,30;h264,1280x720,550k,30" \
--layout all-high \
--video-publishers 40 --subscribers 5 \
--num-per-second 2
Scenario B – More Subscribers than Publishers
Strategy: H.264 + request high/low resolutions.
~/go/bin/lk perf load-test \
--url wss://project.livekit.cloud \
--api-key KEY --api-secret SECRET \
--room TEST_THROUGHPUT \
--duration 3m \
--video-codec h264 \
--video-gen-layers="h264,320x180,150k,20;h264,320x180,350k,30;h264,1280x720,550k,30" \
--layout all-low \
--video-publishers 5 --subscribers 45 \
--num-per-second 2
Scenario C – Virtual Office (Balanced)
Goal: Validate 180p efficiency for "little box" layouts (can be done aswell for 720p tracks)
Strategy: H.264 + request low resolutions.
~/go/bin/lk perf load-test \
--url wss://project.livekit.cloud \
--api-key KEY --api-secret SECRET \
--room TEST_OFFICE_LOW \
--duration 5m \
--video-codec h264 \
--video-gen-layers="h264,320x180,150k,20;h264,320x180,350k,30;h264,1280x720,550k,30" \
--no-simulcast \
--layout all-low \
--video-publishers 25 --subscribers 25 \
--num-per-second 5