Skip to content

Live event streaming load testing

Live streaming loads infrastructure very differently 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 are empty, and origin has to package new segments and deliver them to every viewer at the same time.

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, nobody arrives early. All viewers start at the same moment, and the CDN has nothing cached for the new live manifest or the first few segments.

At kickoff:

  1. Every viewer fetches the master manifest at once. All CDN nodes miss and fall through to origin.
  2. Every viewer fetches the variant playlist, with the same cold-miss pattern.
  3. Every viewer requests the first segment at once. Origin must serve 5,000–50,000+ requests for the same new segment at the same time.
  4. Viewers request later segments in lock-step every segment_duration seconds.

Origin packaging servers must run the encoding/packaging pipeline AND deliver the first segments directly until CDN caches fill. This is where live event infrastructure fails most often.

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

  • Partial segments (chunks). Segments arrive in sub-chunks, so the player does not wait for a full segment.
  • Blocking playlist reload. The player sends a long-polling request to the manifest server. The server holds it until a new segment (or chunk) is available, then responds. From the CDN’s point of view, the variant playlist is nearly always stale.
  • Push hints. The server can hint which resource to prefetch, which saves round-trips.

Under load, blocking playlist reload sharply 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, that is 50,000 persistent connections to your manifest infrastructure, a different scaling limit from standard HLS.

Use a Taurus YAML with an instant 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 two phases: a steep 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 leave during buffering 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 misses are loading origin
Segment p95 drops after first 2–3 minutesCDN cache filled and reached steady state (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. That is long enough to see the CDN cache-hit ratio settle and to catch late viewer spikes (e.g., halftime social shares).
  • Include a manifest refresh in the segment loop for live streams. Manifest re-fetches are a large share 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 VOD load at the same viewer count.
  • Skip the LL-HLS blocking manifest behavior if your platform serves LL-HLS. Without it, you test your manifest server at a small fraction of real connection concurrency.