Skip to content

Concurrent viewers load testing

Scaling a streaming test to thousands of concurrent viewers is not just a matter of increasing VUs. The segment request rate math determines exactly how much load you will drive — and miscalculating it by an order of magnitude means testing at 10% of your intended scale. This page walks through the math, explains how to configure MaxoPerf for high-concurrency viewer tests, and shows what to look for in the results.

Each simulated viewer drives a steady GET request to your CDN at the segment rate:

segment_requests_per_viewer_per_second = 1 / segment_duration_seconds

For a 4-second segment:

  • 1 viewer = 0.25 requests/second
  • 1,000 viewers = 250 requests/second
  • 10,000 viewers = 2,500 requests/second
  • 100,000 viewers = 25,000 requests/second

Plus manifest polls for live streams: for a live HLS stream that refreshes the variant playlist every 4 seconds, add another 0.25 requests/second per viewer. At 10,000 concurrent viewers this adds another 2,500 requests/second to your CDN.

At 5 Mbps (1080p), 10,000 viewers consume 50 Gbps of egress. At 2.5 Mbps (720p) and 70% CDN cache-hit ratio, your origin handles about 7,500 segment GET/s at origin — these are the numbers your capacity planning needs.

Use this worksheet before configuring your test:

ParameterYour value
Target concurrent viewers___
Segment duration (seconds)___
Segment RPS = viewers / segment_duration___
Manifest poll RPS (live only) = viewers / segment_duration___
Total RPS at CDN = segment RPS + manifest RPS___
Expected CDN egress (viewers × bitrate Mbps)___ Gbps

Configuring MaxoPerf for concurrent viewer scale

Section titled “Configuring MaxoPerf for concurrent viewer scale”

In MaxoPerf, one VU = one simulated viewer. Configure your test load profile to match your target:

execution:
- concurrency: 5000 # 5,000 concurrent viewers
ramp-up: 5m # gradual ramp to avoid CDN cold-start distortion
hold-for: 15m # hold long enough to warm CDN caches and observe steady state
scenario: hls-viewer-720p
scenarios:
hls-viewer-720p:
requests:
- label: master-manifest
url: https://cdn.example.com/stream/master.m3u8
method: GET
- label: variant-playlist
url: https://cdn.example.com/stream/720p/playlist.m3u8
method: GET
# Segment loop — represent 2 minutes of playback (30 × 4s segments)
- label: segment
url: https://cdn.example.com/stream/720p/seg-0001.ts
method: GET
- label: segment
url: https://cdn.example.com/stream/720p/seg-0002.ts
method: GET
think-time: 4s
# ... continue through seg-0030 with think-time: 4s between each

Real viewers are geographically distributed. Add multiple runner locations in MaxoPerf to model regional viewer populations:

# In MaxoPerf test configuration (via console or API)
locations:
- location: us-east-1
weight: 40 # 40% North American viewers
- location: eu-west-1
weight: 35 # 35% European viewers
- location: ap-southeast-1
weight: 25 # 25% Asia-Pacific viewers

Different regions will exercise different CDN edge nodes. A segment that is fast from US-EAST may be slow from AP-SOUTHEAST if that PoP’s cache is cold — multi-region tests reveal this before your viewers do.

Chart signalWhat it means
Throughput rises then flattens during rampCDN caches warming — normal and expected
Throughput drops sharply during holdOrigin is throttling or the CDN is shedding requests
Segment p95 latency < segment durationHealthy — viewers are not buffering
Segment p95 latency approaching segment durationWarning — real viewers at p95 are at buffer-starvation risk
Segment p99 latency > segment durationReal viewers in the tail percentile are buffering
Manifest latency rising while segment latency is stableManifest server bottleneck separate from CDN segment delivery

Failure criteria for concurrent viewer tests

Section titled “Failure criteria for concurrent viewer tests”

Set failure criteria in MaxoPerf to fail the run automatically if viewer load exceeds safe thresholds:

CriterionRecommended threshold
segment p95 latency< segment_duration_ms (e.g., < 4000 for 4s segments)
segment error rate< 0.5%
master-manifest p95< 500ms

Do:

  • Use a ramp-up period of at least 2–5 minutes. Instant VU spikes cause CDN cache misses to overwhelm origin in ways that do not reflect real viewer arrival.
  • Hold for at least 10 minutes to observe CDN cache-hit ratio stabilize.
  • Choose runner regions that match your actual viewer geography.

Don’t:

  • Set VU count without accounting for segment think-time. If you omit sleep() or think-time, 1,000 VUs will drive 10–100× the realistic segment request rate for 1,000 viewers.
  • Measure only RPS — measure latency percentiles relative to segment duration. RPS alone does not tell you whether viewers are buffering.