MoQT vs HLS/DASH: The Latency Gap and How to Close It

By moqtap team

MoQT vs HLS/DASH: The Latency Gap

If you stream video today, you almost certainly stream it with HLS or DASH. They won. HTTP-based adaptive streaming took over because it rides the existing web: any CDN caches it, any firewall passes it, any device plays it. That reach is why a single origin can serve millions of concurrent viewers without breaking a sweat.

The price of that reach is latency, and — this is the part worth internalizing — most of it is structural, not a tuning problem. HLS and DASH deliver media by chopping it into segments, publishing a manifest that lists them, and having the player download and buffer several before it starts. Every one of those steps adds delay that no amount of server tuning removes. A glass-to-glass latency of 15–30 seconds was normal for years; even a well-run stream sits in the multi-second range.

MoQT attacks the problem at the layer below: it stops thinking in segments and files, and starts thinking in objects over QUIC. This post is about exactly where the HLS/DASH seconds come from, how the low-latency variants help, and what changes when you move the whole model down to MoQT.

Where the seconds actually go

Standard HLS (RFC 8216) and MPEG-DASH (ISO/IEC 23009-1) share the same shape, and the same latency sources:

Source of delayWhy it existsTypical cost
Segment durationThe encoder can’t publish a segment until it’s complete; the player can’t request it until it exists2–10s per segment (commonly 6s)
Player bufferPlayers hold several segments to survive network jitter and ABR switchesoften 3× segment duration
Manifest pollingThe player learns a new segment exists by re-fetching the playlist/MPDup to one segment interval
TCP head-of-line blockingOne lost packet stalls everything behind it on the connectionvariable, spikes under loss

Stack those up and the classic result is roughly 6s segment × 3-segment buffer ≈ 18 seconds, plus manifest and startup overhead — which is how “streaming is 30 seconds behind live” became a truism. Crucially, shrinking the segment doesn’t fix it cleanly: smaller segments mean more requests, more manifest churn, and worse compression efficiency. Segmentation is a floor you push against, not one you remove.

Low-latency HLS and DASH: clawing it back

The streaming world saw the problem and shipped low-latency extensions:

  • Low-Latency HLS (LL-HLS) breaks each segment into partial segments (“parts”) that publish before the full segment is done, adds blocking playlist reloads (the server holds the request until new media exists, killing the polling delay), and uses preload hints. Realistically this lands in the ~2 second range.
  • Low-Latency DASH uses chunked CMAF with HTTP chunked transfer encoding: the player starts consuming a segment while it’s still being written, rather than waiting for it to close. Similar ~2–3 second territory.

These are real improvements and, for a lot of use cases, good enough. But notice what they do: they slice the segment thinner and stream it sooner. They’re optimizations within the segment-and-HTTP model, and they plateau around a couple of seconds because the model still buffers, still runs over TCP, and still coordinates through a manifest. Getting to true sub-second means changing the model.

What MoQT changes

MoQT throws out the two assumptions that create the floor: media is files and transport is TCP.

  • Objects, not segments. MoQT delivers media as a stream of objects — a frame, a chunk of audio, a part of a group — each publishable the instant it exists. There’s no “wait for the segment to close” and no manifest to poll; a subscription is a standing request and objects arrive as they’re produced. The unit of latency drops from a segment to an object.
  • QUIC, not TCP. Running over QUIC means no head-of-line blocking across streams: a lost packet on one subgroup doesn’t stall the others. It also brings 0-RTT reconnects and connection migration for free.
  • Partial reliability. A late video frame is worthless. MoQT can drop objects that miss their delivery timeout instead of reliably retransmitting stale data — something a TCP-based HTTP stack fundamentally can’t do. Priority decides what to protect when bandwidth tightens.
  • Relay fan-out, not just HTTP caching. The scary part of leaving HLS is usually “but I lose my CDN.” You don’t. MoQT is relay-based: one upstream subscription fans out to thousands of downstream subscribers through a relay tree, the same economics as a CDN — except the unit being multiplied is a live object stream, so a late joiner is milliseconds behind the edge instead of a segment-duration behind.

The net effect is sub-second glass-to-glass while keeping broadcast-scale distribution — which is precisely the MoQ working group’s stated dual goal: a “low-latency media delivery solution” that can also “scale efficiently.”

Side by side

Standard HLS/DASHLow-latency HLS/DASHMoQT
Typical latency15–30s~2–3ssub-second
Delivery unitsegment (file)partial segment / chunkobject
TransportHTTP/TCPHTTP/TCPQUIC (streams + datagrams)
Head-of-line blockingyes (per connection)yesno (across streams)
Handles late dataalways reliable (buffers)always reliablecan drop by priority/timeout
Scale modelHTTP CDN cachingHTTP CDN cachingrelay fan-out
Maturityubiquitous, battle-testedwidely deployedpre-RFC (draft-19), maturing

What you keep, and what actually changes

Moving to MoQT is less of a rip-and-replace than it looks, because the shape of adaptive streaming carries over:

  • ABR still works — you publish multiple quality tracks and the subscriber switches between them at group boundaries, the same idea as switching renditions at segment boundaries, just faster and finer-grained. (Simulcast variants are separate tracks, not subgroups — see the hierarchy post.)
  • Your codecs are unchanged — MoQT is media-agnostic; it carries the same H.264/HEVC/AV1/Opus payloads. The common container mapping (LOC) is deliberately thin.
  • The mental model of “manifest → renditions → segments” becomes “catalog → tracks → objects.” Different nouns, familiar structure.

What genuinely changes: the manifest-polling control loop is gone (replaced by subscriptions), the CDN is a relay tree rather than an HTTP cache, and you inherit a new lever — priority and delivery timeouts — for deciding what to protect and what to drop under pressure.

A realistic migration path

You don’t have to flip the whole stack at once:

  1. Start at the edge that hurts most. Low-latency use cases — live sports, auctions, betting, watch-parties, interactive shows — are where the seconds cost money. Pilot MoQT there while VOD and latency-tolerant live stay on HLS.
  2. Reuse your encoders. Keep producing the same encoded media; change the packaging/delivery layer to publish objects instead of writing segments.
  3. Run them in parallel. Serve HLS and MoQT from the same origin during transition; route capable clients to MoQT and everyone else to HLS.
  4. Measure the gap. Instrument subscribe-to-first-object and inter-object timing so you can prove the latency win rather than assume it.

When HLS/DASH is still the right call

MoQT is not a universal replacement, and pretending otherwise helps no one:

  • VOD and catch-up. If content is pre-recorded and latency is irrelevant, HLS’s HTTP caching is simpler, cheaper, and everywhere. There’s no live edge to be close to.
  • Maximum reach, minimum ops. HLS plays on a decade of devices and requires no relay infrastructure. If your audience is enormous, latency-tolerant, and device-diverse, that ubiquity is hard to beat today.
  • A mature, working pipeline you don’t need to change. If 20-second latency isn’t costing you anything, the migration isn’t free and the ROI may not be there yet.

MoQT wins decisively in the band that HLS/DASH serve worst: large-scale live at genuinely low latency — the place where you currently have to choose between “low latency” (WebRTC, which doesn’t fan out cheaply — see MoQT vs WebRTC) and “massive scale” (HLS, which isn’t low latency). MoQT is the working group’s bet that you shouldn’t have to choose.

Measuring and debugging the difference

The migration case lives or dies on numbers, so measure them directly. moqtap surfaces the latency metrics that matter for a MoQT stream — subscribe-to-first-object, inter-object gap, and per-object arrival timing — alongside QUIC transport stats (RTT, loss, congestion window) that tell you why a stream is behaving the way it is. The live-streaming quality use case walks the workflow, and monitoring tracks these over a running session so you can catch regressions before viewers do.

Further reading

Evaluating a move off HLS and want to see the latency win on real traffic? moqtap Desktop and the WebTransport Inspector decode and time every object across drafts 07 through 19 — so “sub-second” is something you measure, not something you take on faith.