HLS vs DASH: How Adaptive Streaming Actually Delivers Video
The two protocols that carry almost all internet video, compared on segmentation, manifests, codec support, and latency.
Almost every video you watch over the internet arrives through one of two protocols: HLS or MPEG-DASH. They solve the same problem in nearly the same way, which makes the differences between them subtle but consequential, especially if you are building a player, choosing a packaging pipeline, or trying to work out why a stream behaves differently on an iPhone than on a Chromecast.
The Problem Both Protocols Solve
Streaming video over the public internet has an awkward constraint: you have no idea what the viewer's connection will do. It might sustain 40 Mbps for an hour, or it might be a phone on a train that drops to 400 Kbps every time it passes a tunnel. A single fixed-quality file fails badly in both directions, too high and it stalls constantly, too low and you are wasting a good connection on a soft picture.
The solution both protocols landed on is the same: chop the video into short segments, encode the whole thing several times at different quality levels, and let the player switch between those levels segment by segment. This is adaptive bitrate streaming, usually shortened to ABR.
The critical design decision was to run all of this over plain HTTP. Earlier streaming protocols used dedicated servers speaking dedicated protocols, which meant they could not use ordinary web infrastructure. By making every segment a normal HTTP GET for a normal file, HLS and DASH made video cacheable by any CDN, passable through any corporate firewall, and servable from ordinary object storage. That decision is why internet video scaled.
The Manifest: Where the Two Diverge
Both protocols start with a text file describing what is available. The player fetches it first, and everything else follows from it.
HLS uses a two-tier structure of .m3u8 files. The first one the player fetches is the multivariant playlist, a short document listing each quality level with its bandwidth, resolution, and codec, plus a URL. The player picks one and fetches that URL, which is a media playlist: an ordered list of segment files with their durations.
The format is deliberately primitive, line-oriented, tag-prefixed, parseable in about forty lines of code. That simplicity is a large part of why HLS support is everywhere.
DASH uses a single XML document called the MPD, for Media Presentation Description. Where HLS lists things, the MPD describes them structurally: a Period contains AdaptationSets (one per media type, video, audio, subtitles), each AdaptationSet contains Representations (the quality levels), and each Representation describes how to construct its segment URLs.
That SegmentTemplate is the real distinction. Rather than enumerating every segment, DASH gives the player a URL pattern and lets it compute segment names arithmetically. For a two-hour film at four-second segments, that is the difference between a manifest with 1,800 lines and one with about fifteen.
HLS eventually added a similar capability, but the enumerate-everything default remains the common case.
Codec and Container Support
Historically this was the sharpest divide. HLS required MPEG-2 Transport Stream segments (.ts), a container designed in the 1990s for broadcast, carrying meaningful per-packet overhead. DASH used fragmented MP4 from the start.
Since 2016 HLS has also supported fragmented MP4, and in practice most modern pipelines now produce fMP4 for both protocols. This convergence is what made CMAF viable, a single set of segment files that both protocols can reference, which halves storage and doubles CDN cache efficiency.
DASH remains formally codec-agnostic: the spec describes how to deliver segments and says nothing about what is inside them. HLS is more prescriptive about supported combinations, which is a constraint when shipping newer codecs but also means fewer surprising playback failures.
Where Each One Is Actually Supported
This is usually the deciding factor, and it is less about technical merit than about who controls the platform.
The asymmetry is Apple's. HLS is Apple's protocol, and Apple platforms do not ship a DASH implementation. On iOS you can technically play DASH inside a browser using Media Source Extensions, but native app playback and background audio effectively require HLS.
DASH has the advantage of being an actual ISO standard developed by MPEG rather than a single vendor's specification published as an informational RFC. In practice that matters less than the Apple constraint. Most services that operate at scale package both.
Latency
Standard configurations of either protocol run 20 to 30 seconds behind live. The reason is structural: the packager must finish writing a segment before it can be served, the player must buffer two or three segments before starting, and each CDN hop adds a little more. With six-second segments and a three-segment buffer, you are 18 seconds behind before accounting for anything else.
Both protocols added low-latency modes that attack this the same way, by making sub-segment pieces available before the full segment is complete.
LL-HLS introduces partial segments, typically 200 to 500 milliseconds each, announced in the playlist as they become available. It pairs this with blocking playlist reloads: the player requests the playlist for a future segment number and the server holds the request open until that content exists, which removes an entire polling round-trip.
LL-DASH uses HTTP chunked transfer encoding. The server begins responding with a segment while still producing it, and the player parses the bytes as they arrive.
Both can reach two to five seconds of glass-to-glass latency. Both demand considerably more of your CDN, which must support either blocking requests or chunked delivery to origin, many caching configurations buffer a full response before forwarding it, which silently defeats the entire mechanism.
Choosing Between Them
If you are building a service today, the honest answer is that the protocol choice is mostly downstream of your platform targets:
• Any Apple platform in scope? You need HLS. This is not negotiable for native iOS or tvOS apps.
• Browser and Android only? DASH is fine, and its manifest efficiency and codec flexibility are genuine advantages.
• Broad reach across everything? Package once as CMAF and generate both manifests. The segment files are shared; only the manifest differs. This is what most large services do, and the incremental cost over picking one is small.
The protocols have been converging for a decade. Segment formats, low-latency approaches, and encryption schemes are now close enough that the interesting engineering decisions have moved elsewhere, into your encoding ladder, your CDN caching strategy, and your player's adaptation logic.