ABR adaptive bitrate testing
Adaptive Bitrate streaming is not a single-rendition system. Real viewers watch at different quality levels depending on their connection speed, device, and screen size. A load test that only fetches your highest-quality rendition misses the actual traffic mix — and potentially the bottlenecks that only appear under a mixed rendition load.
This page explains how ABR switching works, how to model a realistic viewer mix across renditions, and how to read the results in MaxoPerf.
Before you start
Section titled “Before you start”- Read HLS and DASH manifest and segment testing — this page builds on the player simulation pattern introduced there.
- Have your manifest URLs ready: master manifest, variant playlist URL for each rendition, and sample segment URLs for each rendition.
How ABR renditions affect load
Section titled “How ABR renditions affect load”A typical HLS or DASH stream offers 4–6 renditions, for example:
| Rendition | Bitrate | Segment size (4s) | Bytes/viewer/min |
|---|---|---|---|
| 240p | 400 Kbps | ~200 KB | ~3 MB |
| 480p | 1.2 Mbps | ~600 KB | ~9 MB |
| 720p | 2.5 Mbps | ~1.25 MB | ~18.75 MB |
| 1080p | 5 Mbps | ~2.5 MB | ~37.5 MB |
| 4K | 15 Mbps | ~7.5 MB | ~112.5 MB |
A viewer on a mobile network may consume the 400 Kbps rendition; a desktop viewer on fiber will climb to 1080p. If your test only runs the 4K rendition, you will drive 20–40× more bytes per VU than your average real viewer and will exhaust bandwidth before you hit the viewer concurrency you actually need to test. Conversely, a 240p-only test under-stresses your origin.
Modeling a realistic viewer mix
Section titled “Modeling a realistic viewer mix”Structure your test as multiple scenarios — one per rendition — weighted to reflect your real viewer distribution:
execution: # 60% of viewers on 720p (mobile + mid-tier desktop) - concurrency: 300 ramp-up: 2m hold-for: 10m scenario: viewer-720p
# 30% of viewers on 1080p (desktop, connected TV) - concurrency: 150 ramp-up: 2m hold-for: 10m scenario: viewer-1080p
# 10% of viewers on 480p (constrained mobile) - concurrency: 50 ramp-up: 2m hold-for: 10m scenario: viewer-480p
scenarios: viewer-720p: requests: - label: master-manifest url: https://cdn.example.com/stream/master.m3u8 method: GET - label: variant-playlist-720p url: https://cdn.example.com/stream/720p/playlist.m3u8 method: GET - 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 - label: segment url: https://cdn.example.com/stream/720p/seg-0003.ts method: GET think-time: 4s - label: segment url: https://cdn.example.com/stream/720p/seg-0004.ts method: GET think-time: 4s
viewer-1080p: requests: - label: master-manifest url: https://cdn.example.com/stream/master.m3u8 method: GET - label: variant-playlist-1080p url: https://cdn.example.com/stream/1080p/playlist.m3u8 method: GET - label: segment url: https://cdn.example.com/stream/1080p/seg-0001.ts method: GET - label: segment url: https://cdn.example.com/stream/1080p/seg-0002.ts method: GET think-time: 4s # continue for segment coverage needed...
viewer-480p: requests: - label: master-manifest url: https://cdn.example.com/stream/master.m3u8 method: GET - label: variant-playlist-480p url: https://cdn.example.com/stream/480p/playlist.m3u8 method: GET - label: segment url: https://cdn.example.com/stream/480p/seg-0001.ts method: GET - label: segment url: https://cdn.example.com/stream/480p/seg-0002.ts method: GET think-time: 4sBy running all three execution blocks in parallel, MaxoPerf drives a realistic mixed-bitrate load against your CDN and origin simultaneously.
Simulating bitrate switching within a session
Section titled “Simulating bitrate switching within a session”A viewer who starts on 720p and then switches to 1080p mid-stream creates a different CDN request pattern. To model this, structure a single viewer scenario to switch renditions partway through:
scenarios: viewer-with-quality-switch: requests: # Start on 720p - label: master-manifest url: https://cdn.example.com/stream/master.m3u8 - label: variant-playlist-720p url: https://cdn.example.com/stream/720p/playlist.m3u8 - label: segment-720p url: https://cdn.example.com/stream/720p/seg-0001.ts - label: segment-720p url: https://cdn.example.com/stream/720p/seg-0002.ts think-time: 4s - label: segment-720p url: https://cdn.example.com/stream/720p/seg-0003.ts think-time: 4s # Switch to 1080p — triggers a new playlist fetch + resync - label: variant-playlist-1080p url: https://cdn.example.com/stream/1080p/playlist.m3u8 - label: segment-1080p url: https://cdn.example.com/stream/1080p/seg-0004.ts think-time: 4s - label: segment-1080p url: https://cdn.example.com/stream/1080p/seg-0005.ts think-time: 4s - label: segment-1080p url: https://cdn.example.com/stream/1080p/seg-0006.ts think-time: 4sThe extra variant playlist fetch at the switch point is the detail that matters — CDN origin hit rates can shift significantly when large numbers of viewers simultaneously upgrade their rendition (for example, when a slow CDN region recovers and players all step up at once).
How to read ABR results in MaxoPerf
Section titled “How to read ABR results in MaxoPerf”In the results Overview tab, the per-label breakdown gives you latency for each rendition separately:
| What you see | What it means |
|---|---|
segment-720p p95 < 4000ms | CDN is serving 720p segments within the segment duration — good |
segment-1080p p95 > 4000ms, segment-720p p95 OK | Origin is stressed for large segments; CDN miss-rate is high for 1080p |
variant-playlist-* latency rising | Manifest server under pressure — common when playlist generation is not cached |
Error rate spiking on segment-1080p only | 1080p rendition origin / storage tier is the bottleneck |
Do / don’t
Section titled “Do / don’t”Do:
- Base your rendition mix on real analytics data (average bitrate your users actually consume).
- Label requests with the rendition name so you can isolate which rendition is causing problems.
- Include a bitrate-switch scenario if your platform has frequent quality switches (e.g., mobile on variable networks).
Don’t:
- Test only your highest-quality rendition — it overstresses per-VU bandwidth and masks issues in lower-bitrate delivery paths.
- Assume all renditions perform equally — packaging infrastructure, CDN rules, and storage tiers often differ between renditions.
Where to go next
Section titled “Where to go next”- Concurrent viewers load — scaling the viewer count and calculating the correct VU-to-request-rate relationship.
- Live event streaming load — modeling the spike when viewers switch from a lower bitrate to a higher one simultaneously at live event start.
- Startup time and rebuffering QoE — using per-rendition latency to derive QoE metrics.