ABR (Adaptive Bitrate)

Streaming

ABR encodes one video as several renditions and lets the player choose, segment by segment, which to fetch for the current network and device. It is a technique, not a protocol or codec: HLS and DASH carry it, the client decides, and the CDN caches every rendition separately.

Also known as Adaptive Bitrate Streaming, HTTP Adaptive Streaming, HAS.

11 min read Updated Aug 30, 2026

Full Explanation

ABR is short for adaptive bitrate. It is the technique of encoding one video into several renditions at different bitrates and resolutions. The player then chooses which rendition to download next, one segment at a time. RFC 8216 states the aim for HLS. It “allows a receiver to adapt the bit rate of the media to the current network conditions in order to maintain uninterrupted playback at the best possible quality”. The published survey literature calls the same technique HTTP adaptive streaming (HAS). That survey literature also names the inputs a player weighs: device capabilities, the available quality levels, current network conditions and server load.

ABR is not a codec, not a transport, and not a server feature you switch on. HLS and DASH are the protocols that carry it. Neither protocol is a synonym for ABR. There is no negotiation with the origin. The renditions are pre-encoded, the manifest advertises them, and the client alone decides. For a CDN, that single design choice is the whole story, because every rendition is a separate set of cacheable objects with its own URLs. The ladder multiplies both cache footprint and origin work.

How it works

The publisher encodes one source into several renditions. Each rendition pairs a resolution with a bitrate. The publisher cuts each rendition into segments at the same time boundaries. A manifest describes the result in two levels. In HLS, the Multivariant Playlist lists the variant streams. RFC 8216 called this the Master Playlist. The 2nd edition draft renamed it. Each variant references its own Media Playlist. That Media Playlist lists the rendition’s segments. A playlist is identifiable by a path ending in .m3u8 or .m3u. It is also identifiable by an HTTP Content-Type of application/vnd.apple.mpegurl or audio/mpegurl. DASH is ISO/IEC 23009-1. It uses one XML document instead: the Media Presentation Description. This document is registered with IANA as application/dash+xml, with the file extension .mpd.

The choosing happens entirely on the client. RFC 8216 says only that “Clients should switch between different Variant Streams to adapt to network conditions”. It then declares that “Algorithms used by the client to switch between Variant Streams are beyond the scope of this document”. So the player fetches the manifest and requests the next segment of whichever rendition it prefers. The CDN serves ordinary HTTP objects, addressed by URL. Adaptation costs no server round trip and no session state. That is precisely why ABR works on general-purpose HTTP caches.

The set of renditions is called the bitrate ladder. Its shape is engineering work, not a constant. Apple’s HLS authoring specification publishes nine H.264 16:9 rungs. They range from 145 kb/s at 416x234 to 7800 kb/s at 1920x1080. The specification frames them as “one possible set of bit rate variants”. It calls the numbers initial encoding targets for typical content that you should evaluate against your own material. The same document’s amended tvOS rules say the 145 kb/s variant SHOULD NOT be provided at all. Netflix went further and made the ladder per title. Its per-title encode optimization gives each title a unique ladder “tailored to its specific complexity characteristics”. It chooses rungs so that the perceptual difference between two adjacent rungs falls just below one just-noticeable-difference (JND). This keeps switches smooth and keeps the rung count as low as possible.

Players pick rungs using an ABR algorithm. These algorithm families differ in what they measure.

  • Throughput-based (rate-based) rules read recent download speed. They take the highest rung that fits. The dash.js ThroughputRule asks its throughput controller for a safe average throughput and requests the optimal representation for that bitrate. It only proposes a switch while the buffer is loaded or the stream is dynamic.
  • Buffer-based rules watch the playback buffer instead. Netflix’s BBA work is by Huang et al. at SIGCOMM 2014. It defines an algorithm as buffer-based if it picks the video rate as a function of current buffer occupancy. Two A/B tests each had over half a million real users on three continents. They cut the rebuffer rate by 10 to 20 percent against Netflix’s then-default algorithm, at a similar average video rate. The same paper qualifies the idea. Capacity estimation is unnecessary in steady state. Throughput estimation still matters during startup, while the buffer is growing from empty.
  • BOLA is by Spiteri et al. (arXiv:1601.06748). It formulates rung choice as utility maximisation and proves a bound. Its time-average utility is within an additive O(1/V) of optimal, for a control parameter V tied to buffer size. Unlike earlier work, it needs no bandwidth prediction. It ships in dash.js as BolaRule.
  • Hybrid players run both signals but do not average them. In dash.js, both rules are active by default. Its AbrController switches per media type based on buffer level. It uses throughput below the hybrid switch buffer time, which is 12 seconds by default. It uses BOLA at or above that level. It falls back to throughput only below half that value, so the two cannot oscillate. Its ABRRulesCollection enforces the rule “Only Throughput or Bola are active at the same time”. It then merges the surviving rules’ requests, preferring the lowest proposed bitrate within a priority band. Media3 ExoPlayer’s AdaptiveTrackSelection is bandwidth-led with buffer guards. It treats 0.7 of the measured bandwidth as usable. It requires 10 seconds of buffered media before stepping up. It steps down only once the buffer falls below 25 seconds.

Switching is only seamless if the renditions line up. Both specifications make that a server-side obligation, not a player problem. RFC 8216 requires that variant streams present the same content. It requires that matching content carry matching timestamps. It requires that every Media Playlist share the same target duration. For broadest compatibility, it also asks variants to carry the same encoded audio bitstream, so switches do not glitch audibly. Apple’s authoring rules add three alignment requirements. Video segments MUST start with an IDR frame. IDRs SHOULD appear every two seconds. All variants and renditions SHOULD place segment boundaries at the same points in time. That last rule is a MUST in Apple’s amended rules for AirPlay 2-enabled TVs. CMAF (ISO/IEC 23000-19) formalises this as a switching set, whose tracks can be switched at fragment boundaries. Apple notes that HLS playlists and a DASH MPD can address the very same CMAF objects, “thereby allowing efficient caching even when delivering to multiple platforms”. Without aligned decode points, the decoder waits for the next keyframe on the new rung. The switch then stalls or shows artifacts.

Why it matters for a CDN

Each rung has distinct segment URLs. So each rung gets its own cache key and its own working set. A five-rung ladder means five times the objects for one title. Audience demand is divided across those rungs, rather than concentrated on one. That division is what hurts: caches are not archives. Fastly documents plainly that everything in its cache is ephemeral. It “may be evicted by the platform before it expires depending on how frequently it is used”. This is the LRU behaviour every CDN shares. So the rungs few viewers select are the first to fall out. They are also the ones that keep going back to origin. Ladder width therefore trades directly against cache hit ratio, storage footprint and origin cost. It is worth measuring per-rung request share before adding a rung.

Live ABR adds a second cost. Segments are immutable and cache well. Playlists change every target duration and are requested by every viewer of every rendition. So playlist handling dominates request volume at the live edge. Apple’s low-latency server profile is explicit about the cache lifetimes it expects. It expects successful responses to blocking playlist requests to be cached for six target durations. It expects successful responses to non-blocking playlist requests to be cached for half a target duration. It expects HTTP caches to set the Age header, so clients can judge how stale the playlist they received is.

What CDNs do

The core path is the same at every CDN. Segment objects are rendition-specific and cached by URL. The adaptation decision is left to the client. The differences are at the origin edge and on the live path.

  • Origin shielding. CloudFront Origin Shield is an opt-in extra cache layer in front of the origin. Requests for an object it does not hold are consolidated with other requests for the same object, “resulting in as few as one request going to your origin”. AWS lists origins that provide just-in-time packaging for live streaming among its use cases. AWS also says it may not be a good fit for content with low cacheability or content that is infrequently requested. That is exactly the profile of a rarely selected top rung.
  • Request collapsing on the live edge. Apple’s low-latency server configuration profile expects that “CDNs and other proxy caches recognize blocking requests for Playlists and Media Segments whose cache fill is already pending, and hold the duplicate requests until they can be delivered from that cache fill”. This is what keeps a live packager from being hit once per viewer.
  • Serving the whole ladder from one place. The same profile requires that each server offer the entire set of variant streams in the Multivariant Playlist. This lets a player change rung without establishing a new connection to a different host. Splitting rungs across hostnames or providers defeats that.

Watch out for

Segment duration is the tension every ABR deployment has to resolve. Apple’s authoring rules say target durations SHOULD be 6 seconds. The HLS 2nd edition draft calls 6 seconds typical, because the cost of going shorter is not only more requests. As the draft puts it, “A shorter Target Duration reduces latency but also reduces available buffer, handicaps adaption and increases delivery overhead, increasing the likelihood of playback stall”. Short segments start and adapt faster. Long segments compress better and generate fewer requests. Independently of that choice, the draft recommends a GOP of one to two seconds. Smaller GOPs allow faster switching between renditions.

Low latency does not fix that trade-off by shortening segments. It sidesteps the trade-off instead. A segment cannot be distributed until it has been completely encoded and packaged. So a long segment produced in real time adds a delay equal to its own duration. Low-latency HLS and LL-DASH therefore publish partial segments (CMAF chunks) alongside the parent segment. Apple’s Low-Latency Mode is the combined use of partial segments, blocking playlist reload, and preload hinting. Clients SHOULD verify that a server meets that profile before playing at a delay-from-live of less than two target durations. A partial segment carrying an independent frame should be marked INDEPENDENT. That marking is what lets a player join or change rendition without waiting for the parent segment to finish.

Two misreadings cost real money. ABR is not “fetch the highest rung”. A player that ignores its buffer rebuffers. That is the failure the buffer-based research set out to measure. ABR is also not a property of a single file. Publishing one rendition produces a stream that cannot adapt, no matter what the player does. So does publishing renditions whose keyframes do not align.

Best practice

  • Derive the rung count and bitrates from the content and from measured per-rung demand, not from a fixed template.
  • Keep one target duration across every rendition. Force keyframes at identical timestamps, with an IDR opening every video segment.
  • Keep audio encoding identical across variants. Then a video rung change does not glitch the audio.
  • Serve every rung from the same host and provider. Then a switch reuses the connection.
  • Put a shield in front of just-in-time packaging. Confirm the CDN collapses concurrent misses for the same segment before a live event, rather than during one.
  • Cache segments long and playlists briefly. Expose Age so players can tune in accurately.

Examples

# HLS master playlist (M3U8) showing ABR variants
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=640x360
360p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720
720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/playlist.m3u8

# FFmpeg command to create HLS ABR variants
ffmpeg -i input.mp4 \
  -map 0:v -map 0:a -map 0:v -map 0:a \
  -b:v:0 500k -s:v:0 640x360 \
  -b:v:1 2000k -s:v:1 1280x720 \
  -f hls -hls_time 4 \
  -master_pl_name master.m3u8 \
  -var_stream_map "v:0,a:0 v:1,a:1" \
  stream_%v/playlist.m3u8

# Cache-Control for HLS segments (cache aggressively)
# Segments are immutable once created
Cache-Control: public, max-age=31536000, immutable

# Cache-Control for live manifest (short TTL)
Cache-Control: public, max-age=1

Frequently Asked Questions

ABR encodes one video as several renditions and lets the player choose, segment by segment, which to fetch for the current network and device. It is a technique, not a protocol or codec: HLS and DASH carry it, the client decides, and the CDN caches every rendition separately.

# HLS master playlist (M3U8) showing ABR variants
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=640x360
360p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720
720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/playlist.m3u8

# FFmpeg command to create HLS ABR variants
ffmpeg -i input.mp4 \
  -map 0:v -map 0:a -map 0:v -map 0:a \
  -b:v:0 500k -s:v:0 640x360 \
  -b:v:1 2000k -s:v:1 1280x720 \
  -f hls -hls_time 4 \
  -master_pl_name master.m3u8 \
  -var_stream_map "v:0,a:0 v:1,a:1" \
  stream_%v/playlist.m3u8

# Cache-Control for HLS segments (cache aggressively)
# Segments are immutable once created
Cache-Control: public, max-age=31536000, immutable

# Cache-Control for live manifest (short TTL)
Cache-Control: public, max-age=1

Yes. ABR (Adaptive Bitrate) is also known as Adaptive Bitrate Streaming, HTTP Adaptive Streaming, HAS. ABR encodes one video as several renditions and lets the player choose, segment by segment, which to fetch for the current network and device. It is a technique, not a protocol or codec: HLS and DASH carry it, the client decides, and the CDN caches every rendition separately.

Related CDN concepts include: