StreamTest

What causes live edge drift in HLS and how to test for it

Live edge drift is the growing or shrinking gap between the actual live moment and the point in the stream a player is currently showing, and it is tested by tracking that gap over several minutes rather than checking it once. A single snapshot cannot distinguish normal buffering distance from a drift that is steadily getting worse.

Drift has two distinct failure directions: a player that falls progressively further behind the live edge (falling behind), and a player that catches up too aggressively and starts skipping content or introducing audible/visible seams (over-correcting). Testing for drift means watching the trend, not the instantaneous value.

How do you actually measure edge drift over time?

Poll the live media playlist at a fixed interval and, for each poll, take the #EXT-X-PROGRAM-DATE-TIME of the last segment or part, add its duration, and compare that to current wall-clock time; the difference is the playlist's distance from the true live edge at the origin. Separately, track what timestamp the player is actually rendering, and the gap between the two is the player's edge drift.

A stable stream shows this gap oscillating within a narrow band close to the expected buffer target (roughly TARGETDURATION times the live sync buffer count most players use, commonly three segments). A drifting stream shows the gap trending in one direction over minutes, not just jittering.

What playlist-side conditions cause the live edge itself to drift?

If the encoder's wall-clock is not synchronized (no NTP, or a drifting local clock), EXT-X-PROGRAM-DATE-TIME values will be wrong relative to real time even though segment durations and sequencing are perfectly consistent internally. This makes every downstream latency measurement wrong without any playback symptom, since the player still receives valid, well-formed segments.

Variable segment duration around an encoder hiccup (a segment that runs long because a keyframe was late) shifts the relationship between MEDIA-SEQUENCE and wall-clock time for every segment after it, unless PROGRAM-DATE-TIME is recalculated per segment rather than assumed from a fixed cadence.

What player-side behaviour makes a session fall behind the live edge?

A player fetching a live playlist on a fixed timer that is longer than the actual segment cadence will always be looking at a stale playlist snapshot, and each stale fetch adds one segment duration of delay that compounds if it happens repeatedly. This is common in naive polling implementations that do not adjust their reload interval to TARGETDURATION.

Rebuffering events are the other major cause: after a stall, many players resume playback from where they left off in the buffer rather than seeking forward to the new live edge, so a ten-second stall becomes a permanent ten-second drift unless the player explicitly detects and corrects for it.

What player-side behaviour causes over-correction instead?

A player that aggressively speeds up playback (1.02x-1.1x, typically inaudible) to close a drift gap can overshoot if its correction logic does not account for its own measurement lag, briefly catching right up to segments still being written and then having to slow down or stall waiting for more data. This produces a sawtooth pattern in the drift measurement rather than a smooth return to target.

A player that seeks forward hard to "catch up" instead of speeding up smoothly will produce a visible or audible jump cut, which is more jarring than gradual drift even though the resulting latency number looks better.

How does the live sliding window size relate to drift tolerance?

The number of segments kept in a live media playlist sets the maximum drift a player can have before it runs off the back of the window entirely and gets an HTTP 404 or 410 on a segment that has already rolled off. A three-segment window with a six-second TARGETDURATION gives roughly eighteen seconds of tolerance; a six-segment window doubles that headroom for the same segment duration.

A shorter window forces tighter latency but is less forgiving of transient network stalls; a longer window tolerates more drift before failure but increases the achievable minimum latency, since clients are generally expected to start a few segments back from the edge, not on the very last one.

What does a CDN or proxy add to measured drift that the origin does not show?

Edge caching a live media playlist for even a few seconds, when it should be near-uncacheable, adds that cache duration directly to every downstream player's drift, and this is invisible if you only test against the origin. Compare the playlist fetched from the CDN edge against the same fetch against the origin directly to isolate CDN-added delay.

Multiple CDN PoPs with independent, out-of-sync caches can also cause different viewers to sit at different points in the stream even when they joined at the same real-world moment, which shows up as inconsistent drift complaints across a viewer base rather than a single measurable number.

Step by step

  1. Poll the live media playlist every few seconds for at least two to three minutes.
  2. Record PROGRAM-DATE-TIME plus segment/part duration against wall clock on each poll to get the origin's edge-to-real-time offset.
  3. In the player, log the timestamp of the content currently rendering, using PROGRAM-DATE-TIME correlation if the player exposes it.
  4. Plot the gap between rendered timestamp and wall clock over the session length and look for a trend, not just a single value.
  5. Repeat the same measurement fetching the playlist from the CDN edge and from the origin directly to isolate CDN-added delay.
  6. Force a rebuffer (throttle the network briefly) and check whether the player's drift returns to baseline afterwards or stays elevated.

Run it yourself

Free, no sign-up, and every finding links to an explainer.

Frequently asked questions

Is some live edge drift always normal in HLS?
Yes; players deliberately stay a few segments behind the true live edge as a buffer against network jitter, so a stable offset of roughly two to three segment durations is expected behaviour, not a defect. The concern is a gap that keeps growing over the session, not a constant one.
Why does drift get worse only after long viewing sessions?
Long sessions accumulate small errors from every rebuffer, stale playlist fetch, or clock rounding along the way, and if the player has no active correction logic these small errors only ever add up rather than cancel out. A short test session can look fine while a multi-hour one reveals steadily increasing drift.
Can server-side clock drift cause this even with a perfect player?
Yes; if the encoder's system clock is not NTP-synchronized, EXT-X-PROGRAM-DATE-TIME values are wrong from the moment they are written, so any drift measurement based on them will be wrong regardless of how correctly the player behaves. Checking the encoder host's NTP sync status is a standard first step when drift measurements look implausible.
Does a bigger live sliding window fix drift?
A bigger window only increases how much drift a player can tolerate before running off the back of the playlist; it does not reduce or fix the underlying cause of the drift itself. Fixing the actual cause (polling interval, rebuffer recovery, CDN caching) is still necessary even with a generous window.

HLS findings, explained

Read next

Last reviewed 2026-09-16.