Skip to content

Live event streaming load testing

Live streaming has a fundamentally different load profile from VOD. When a sports match begins, a concert starts, or a company announces live earnings, thousands of viewers arrive in the same 30-second window. This kickoff spike is the most dangerous load event in live streaming — manifests are cold, CDN caches have nothing, and origin must simultaneously package and deliver new segments to every viewer.

This page shows how to model the live-event kickoff spike in MaxoPerf, including Low-Latency HLS (LL-HLS) and Low-Latency DASH (LL-DASH) specifics.

For VOD, viewers arrive at different times. By the time you have 10,000 concurrent viewers, your CDN has had hours to warm its caches as earlier viewers fetched the same segment URLs. For live events, no one arrived early — all viewers start at the same moment. The CDN has zero cached content for the new live manifest and the first several segments.

At kickoff:

  1. Every viewer simultaneously fetches the master manifest — all CDN nodes miss and fall through to origin.
  2. Every viewer fetches the variant playlist — same cold-miss pattern.
  3. The first segment is requested by every viewer at once — origin must serve 5,000–50,000+ requests for the same new segment simultaneously.
  4. Subsequent segments are requested in lock-step every segment_duration seconds.

Origin packaging servers must handle both the encoding/packaging pipeline AND direct delivery of the first segments before CDN caches fill. This is the most common point of failure in live event infrastructure.

Low-Latency HLS (LL-HLS) and LL-DASH reduce playback delay to 1–3 seconds using:

  • Partial segments (chunks) — segments are delivered in sub-chunks, reducing the wait for a full segment.
  • Blocking playlist reload — the player makes a long-polling request to the manifest server, which blocks until a new segment (or chunk) is available, then responds. This keeps the variant playlist nearly always stale from the CDN’s perspective.
  • Push hints — the server can hint which resource to prefetch, reducing round-trips.

Under load, blocking playlist reload significantly increases manifest server connections. Each viewer holds an open connection to the manifest server for the blocking poll duration (typically 2–6 seconds). At 50,000 viewers, this means 50,000 persistent connections to your manifest infrastructure — a different scaling constraint than standard HLS.

Use a Taurus YAML with an instantaneous ramp to model the kickoff — most viewers arrive within the first 30–60 seconds:

execution:
- concurrency: 10000 # target concurrent viewers at peak
ramp-up: 30s # 30-second ramp models typical viewer surge at event start
hold-for: 60m # 60-minute hold for a typical live event
scenario: live-hls-viewer
scenarios:
live-hls-viewer:
requests:
# Kickoff: fetch fresh manifest (CDN cold at event start)
- label: master-manifest
url: https://live.example.com/event/master.m3u8
method: GET
assert:
- contains:
subject: body
value: '#EXTM3U'
# Fetch the live variant playlist (always fresh for live)
- label: variant-playlist
url: https://live.example.com/event/720p/playlist.m3u8
method: GET
# Segment fetch loop — real-time cadence
# Live segments rotate — in production you'd parse the playlist
# for load testing, model with a fixed segment pool cycling through recent IDs
- label: live-segment
url: https://live.example.com/event/720p/seg-live-001.ts
method: GET
- label: live-segment
url: https://live.example.com/event/720p/seg-live-002.ts
method: GET
think-time: 4s
- label: live-segment
url: https://live.example.com/event/720p/seg-live-003.ts
method: GET
think-time: 4s
# Live: re-fetch variant playlist periodically (every segment interval)
- label: variant-playlist-refresh
url: https://live.example.com/event/720p/playlist.m3u8
method: GET
- label: live-segment
url: https://live.example.com/event/720p/seg-live-004.ts
method: GET
think-time: 4s

Most live events have a distinct two-phase shape: an aggressive ramp at kickoff, then a plateau. You can model this with Taurus multi-stage execution or with k6 stages:

// k6 — live event load profile
export const options = {
stages: [
// Phase 1: Kickoff spike — everyone arrives in the first 60 seconds
{ duration: '60s', target: 15000 }, // surge to 15K viewers
// Phase 2: Plateau — steady viewer count for the event duration
{ duration: '55m', target: 12000 }, // slight drop as early-joiners leave; steady count
// Phase 3: Event end ramp-down
{ duration: '5m', target: 0 },
],
};

The slight VU drop from 15,000 to 12,000 after the kickoff is realistic — some viewers bounce during buffering events caused by the cold-cache surge, and others join late.

For LL-HLS, each viewer holds a blocking connection to the manifest endpoint during each segment interval. Model this with a longer think-time and an explicit manifest re-fetch in the loop:

scenarios:
ll-hls-viewer:
requests:
- label: master-manifest
url: https://live.example.com/event/master.m3u8
- label: variant-playlist-blocking
url: https://live.example.com/event/720p/playlist.m3u8?_HLS_msn=&_HLS_part=
method: GET
# Blocking poll — expect ~2s response time for next chunk notification
- label: ll-chunk
url: https://live.example.com/event/720p/chunk-000001.m4s
method: GET
- label: variant-playlist-blocking
url: https://live.example.com/event/720p/playlist.m3u8?_HLS_msn=&_HLS_part=
method: GET
think-time: 1s
- label: ll-chunk
url: https://live.example.com/event/720p/chunk-000002.m4s
method: GET

Under LL-HLS load, watch manifest-server connection counts and response time. The blocking endpoint is the most common LL-HLS bottleneck.

After the run, look for:

SignalWhat it means
Segment p95 > segment duration during rampViewers are buffering at kickoff — CDN is miss-loading origin
Segment p95 drops after first 2–3 minutesCDN cache filled — steady state; this is the expected profile
Manifest latency spikes at kickoff, recoversOrigin manifest server handled the concurrent session surge
Manifest latency stays high throughoutManifest server is a sustained bottleneck
Error rate at kickoff, recoversOrigin shed requests under cold-miss storm; review origin autoscaling triggers

Do:

  • Use a short ramp-up (30–90 seconds) to model the kickoff. Live events do not have 5-minute viewer ramps.
  • Hold the test for the full expected event duration — long enough to see CDN cache-hit ratio stabilize and to catch late-arriving viewer spikes (e.g., halftime social shares).
  • Test with a manifest refresh in the segment loop for live streams — manifest re-fetches are a significant fraction of total live requests.

Don’t:

  • Use the same gradual 5-minute ramp you use for VOD tests — a slow ramp warms CDN caches artificially and hides the cold-start failure mode.
  • Forget that live segments have short TTLs and low CDN cache-hit rates — live origin load is 3–10× higher than equivalent VOD load at the same viewer count.
  • Skip the LL-HLS blocking manifest behavior if your platform serves LL-HLS — omitting it means your manifest server is tested at a small fraction of real connection concurrency.