Concurrent viewers load testing
Scaling a streaming test to thousands of concurrent viewers takes more than a higher VU count. The segment request rate math sets exactly how much load you drive. Get it wrong by an order of magnitude and you test at 10% of your intended scale. This page walks through the math, shows how to configure MaxoPerf for high-concurrency viewer tests, and explains what to look for in the results.
Before you start
Section titled “Before you start”- Read HLS and DASH manifest and segment testing for the player simulation pattern this page builds on.
- Have a realistic segment duration for your stream (typically 2, 4, or 6 seconds).
Segment request rate math
Section titled “Segment request rate math”Each simulated viewer drives a steady GET request to your CDN at the segment rate:
segment_requests_per_viewer_per_second = 1 / segment_duration_secondsFor 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
Live streams add manifest polls. 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, that is another 2,500 requests/second at 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 750 segment GET/s. Your capacity planning needs these numbers.
Fill in this worksheet before you configure your test:
| Parameter | Your 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 eachMulti-region viewer distribution
Section titled “Multi-region viewer distribution”Real viewers are spread across regions. Add several 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 viewersEach region hits 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. A multi-region test shows this before your viewers see it.
Reading the results
Section titled “Reading the results”What to look for
Section titled “What to look for”| Chart signal | What it means |
|---|---|
| Throughput rises then flattens during ramp | CDN caches warming (normal and expected) |
| Throughput drops sharply during hold | Origin is throttling or the CDN is shedding requests |
| Segment p95 latency < segment duration | Healthy: viewers are not buffering |
| Segment p95 latency approaching segment duration | Warning: real viewers at p95 are at buffer-starvation risk |
| Segment p99 latency > segment duration | Real viewers in the tail percentile are buffering |
| Manifest latency rising while segment latency is stable | Manifest 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 so the run fails automatically when viewer load goes past safe thresholds:
| Criterion | Recommended threshold |
|---|---|
segment p95 latency | < segment_duration_ms (e.g., < 4000 for 4s segments) |
segment error rate | < 0.5% |
master-manifest p95 | < 500ms |
Do / don’t
Section titled “Do / don’t”Do:
- Use a ramp-up period of at least 2–5 minutes. An instant VU spike floods origin with CDN cache misses in a way real viewer arrival does not.
- Hold for at least 10 minutes so you can watch the CDN cache-hit ratio settle.
- Choose runner regions that match your actual viewer geography.
Don’t:
- Set VU count without accounting for segment think-time. If you omit
sleep()orthink-time, 1,000 VUs will drive 10–100× the realistic segment request rate for 1,000 viewers. - Measure only RPS. Measure latency percentiles against segment duration too, because RPS alone does not tell you whether viewers are buffering.
Where to go next
Section titled “Where to go next”- Live event streaming load: model the kickoff spike when thousands of viewers arrive in the same second.
- Startup time and rebuffering QoE: turn MaxoPerf latency into rebuffer ratio estimates.
- ABR adaptive bitrate testing: mix renditions across your viewer population.
- Failure criteria / pass-fail gates: automate the segment latency threshold check.