Skip to content

LiveKit Load Tester CLI (Customized)

This document describes how to install, configure, and utilize the customized LiveKit Load Tester.

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

  1. Go – Ensure Go is installed on your machine.
  2. Git LFS – Required to pull large video assets used for testing.
  3. Netdata – A Netdata instance must be running at http://localhost:19999 to fetch CPU metrics.

Step-by-Step Install

Clone the repository and initialize Git LFS:

git clone git@github.com:StartingQuoTechDivision/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.

  1. Log in to the LiveKit Cloud Dashboard.
  2. Navigate to Settings > Keys to retrieve your API Key and API Secret.
  3. 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/

Important

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% → Safe
    • 70–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% → Excellent
    • 0.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

```