Hakari

What is LLHLS?

LLHLS (Low-Latency HLS) is Apple's official extension to HLS for sub-3-second live streaming. It runs on the same HTTP infrastructure and the same fMP4 segment format — the innovation is in the manifest and the request patterns.

End-to-end latency from camera to viewer: typically 2–4 seconds in production, vs 15–30s for classic HLS. Good enough for live sports, auctions, second-screen experiences, co-watching. Not as low as WebRTC (under 1 second), but dramatically easier to deploy at scale because it's just CDN-cacheable HTTP.

How it works — the three tricks

1. Parts

Where classic HLS emits a 6-second segment, LLHLS additionally emits that segment's parts (sub-segments of ~0.3–1s) as they're encoded. Clients can play parts before the full segment is done.

#EXT-X-PART:DURATION=0.500,URI="part_245_0.m4s",INDEPENDENT=YES
#EXT-X-PART:DURATION=0.500,URI="part_245_1.m4s"
#EXT-X-PART:DURATION=0.500,URI="part_245_2.m4s"
#EXT-X-PART:DURATION=0.500,URI="part_245_3.m4s"
#EXTINF:2.000,
seg_245.m4s

The INDEPENDENT=YES on the first part means it contains a keyframe — players can start decoding here.

2. Blocking playlist reload

Classic HLS: client polls the playlist every 2–6s looking for new segments. Wasteful and slow.

LLHLS: client asks the server "give me the playlist version that contains segment X, part Y, and hold the connection until you have it." — with _HLS_msn=245&_HLS_part=2 query params. The server holds the request until that part is ready, then responds.

Result: zero polling delay. The playlist arrives the instant new content exists.

3. Preload hints

Even better: the server can tell the client "the next part is coming at this URL" before the part exists:

#EXT-X-PRELOAD-HINT:TYPE=PART,URI="part_245_4.m4s"

The client can start the HTTP request for that part before it's ready. When the part is encoded, the server flushes it into the already-open connection. Zero-round-trip delivery.

Manifest example

#EXTM3U
#EXT-X-VERSION:9
#EXT-X-TARGETDURATION:2
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=1.500
#EXT-X-PART-INF:PART-TARGET=0.500
#EXT-X-MEDIA-SEQUENCE:245
#EXT-X-MAP:URI="init.m4s"
#EXT-X-PART:DURATION=0.500,URI="part_245_0.m4s",INDEPENDENT=YES
#EXT-X-PART:DURATION=0.500,URI="part_245_1.m4s"
#EXT-X-PART:DURATION=0.500,URI="part_245_2.m4s"
#EXT-X-PART:DURATION=0.500,URI="part_245_3.m4s"
#EXTINF:2.000,
seg_245.m4s
#EXT-X-PART:DURATION=0.500,URI="part_246_0.m4s",INDEPENDENT=YES
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="part_246_1.m4s"

Browser support

LLHLS is supported by:

  • Safari — native, desktop + iOS.
  • hls.js 1.1+ — all Chromium + Firefox browsers. Used by essentially every web player.
  • OvenPlayer — open-source, low-latency focus.
  • video.js 8+ via the HLS contrib.

Players that don't understand LLHLS tags (older devices, embedded players) ignore them and fall back to regular HLS segment playback — slightly higher latency but no breakage. This graceful degradation is why LLHLS is a safe default.

LLHLS on Hakari

LLHLS is the default when you create a stream. Two URL flavors are provisioned:

Resilient (default)

https://stream.hakari.cloud/app/<streamKey>/index.m3u8

This goes through Hakari's resilience layer, which sits between the live origin and the edge. It does two critical things:

  1. Keepalive injection. When the broadcaster's upload stalls briefly, the layer synthesizes segments that duplicate the last real frame. The player's timer keeps advancing, no stall.
  2. Graceful fallback. If the live origin goes fully down but the VOD recording is mid-upload, the edge detects the missing live session and serves the recorded copy transparently. See VOD fallback.

Direct

https://stream.hakari.cloud/app/<streamKey>/d/llhls.m3u8

Unbuffered path straight from the live origin. Slightly lower latency (no resilience layer), but no cushion — if the broadcaster hiccups, the client stalls.

For most use cases the resilient URL is the better default. Use direct when you're chasing the absolute lowest latency and your broadcaster has rock-solid upstream.

VOD fallback

If the live pipeline goes down mid-broadcast but the stream had recording enabled, the Hakari edge transparently falls back to the recorded VOD copy. The viewer's player keeps polling the same index.m3u8 URL; after ~10 seconds the response switches from live bytes to the recorded copy. No player reconnect.

Cache headers on recorded segments are aggressive (max-age=31536000, immutable) so subsequent viewers pull from the edge's local cache without round-tripping to storage.

DVR

Toggle DVR on a stream and Hakari keeps a large window of historical parts addressable. Viewers with DVR-aware players (OvenPlayer, hls.js with liveDurationInfinity: false) can scrub back that far. See DVR.

Signed URLs

Signed playback works the same way across all LLHLS flavors. Hakari preserves ?policy=&signature= through every rewritten URI so derivative requests stay valid.

  • HLS — the non-low-latency original.
  • WebRTC — sub-second latency when you can't afford 2s.
  • CMAF / fMP4 — the segment format LLHLS uses.
  • Streams — the full guide to picking protocols per stream.