Low-latency ingest requirements
Each stage of the capture–encode–transmit pipeline introduces delay: encoders buffer frames for better compression decisions, the network adds jitter, and downstream transcoders and segmenters wait for clean GOP boundaries. To minimize ingest-side latency, tune the encoder and pipeline for real-time operation:- Disable B-frames and scene-cut detection. Many codecs use B-frames and variable GOPs for compression efficiency. These require buffering multiple frames and cause unpredictable keyframe spacing. FFmpeg’s x264 encoder exposes a special tuning preset for live streaming:
-tune zerolatency, which disables B-frames and reduces internal buffering. - Use a fast preset and 4:2:0 color format. Real-time encoding trades compression for speed. A
veryfastorultrafastpreset lowers CPU usage and latency. Constraining the pixel format toyuv420p(I420) avoids 4:4:4 output, which some ingest servers reject when operating in baseline mode. - Fix the GOP length. Set a constant GOP (group of pictures) so that keyframes arrive at predictable intervals. DASH/HLS segmenters rely on consistent I-frame spacing to start segments; a wandering GOP breaks segmentation and forces downstream buffers to wait. A common starting point is a 1-second GOP: for 30 fps content, set
-g 30 -keyint_min 30 -sc_threshold 0and disable B-frames (-bf 0). This creates exactly one IDR frame every 30 frames. - Minimize muxing and packet buffers. Add
-flags low_delay,-fflags +nobuffer+flush_packets,-max_delay 0, and-muxdelay 0so that packets are flushed immediately rather than accumulated. These options are especially important for protocols like RTMP or SRT that otherwise buffer data internally. - Use SRT latency and mode parameters. When streaming over SRT, specify an application-layer buffer in the URI. It should be large enough to cover the round-trip time plus any network jitter.
zerolatency tune, enforces a 1-second GOP, and sends the output as MPEG-TS via SRT. The latency parameter is in microseconds (1.5 s), and mode=caller initiates the SRT connection:
Low-latency playback problems
Low-latency playback is stable only when the encoder, packager, CDN, and player all keep the same timing model. A stream that the CDN delivers correctly can still become unstable — if the player tracks the live edge too closely, or catches up too aggressively after a delay. The most common symptoms are:- Playback starts at low latency, then gradually drifts to a higher delay.
- A single slow segment causes a stall, and the extra latency remains after playback resumes.
- The player oscillates between stall and catch-up instead of returning smoothly to the target latency.
- The same stream is stable in the Gcore built-in player but unstable in a custom hls.js, dash.js, native, or TV player.
Slow segments and permanent latency increase
When a live player stalls, the live edge continues to move forward, but the viewer’s playback position does not:Aggressive catch-up and recurring stalls
Many low-latency players increase playback speed after they fall behind the live edge. An aggressive catch-up rate can drain the buffer faster than the stream refills it. Suppose a 6-second segment is normally delivered in 5.6 seconds, and one slow segment is delivered in 6.85 seconds:
At 1.5x speed, a 6-second segment must arrive in less than
6 / 1.5 = 4 seconds to avoid draining the buffer. If the stream normally arrives in about 5.6 seconds, 1.5x catch-up is mathematically incompatible with stable playback. Use a lower catch-up cap — 1.05x or 1.1x.
Ingest pauses and delayed segments
An artificial pause in the ingest pipeline creates a concentrated delay in the last chunks of one segment instead of a uniform slowdown. Common causes include: a looped test source restarting its file (-codec copy with finite input), encoder CPU overload, and network jitter spikes.
The CDN delivers chunks as soon as they exist, but cannot send chunks that the origin has not produced yet. For test loops, prefer re-encoding with stable real-time settings instead of -codec copy, or use a long continuous source file. For production streams, keep a fixed GOP, disable B-frames, and monitor ingest jitter and encoder CPU load.
Balance latency and playback stability
Lower latency means the player keeps less media in its buffer. This reduces delay, but leaves less time to absorb encoder jitter, network jitter, CDN cache misses, device CPU spikes, ABR switches, and slow segment generation. Higher latency provides more buffered media and more stable playback, but the viewer is farther behind the live event.Configure custom players
The Gcore built-in player is already tuned for low-latency playback. For custom players, start with a 4-second target delay and a 1.1x catch-up cap, then adjust these values based on rebuffering and measured live latency.hls.js
Use hls.js for LL-HLS playback in browsers that do not use native HLS playback. The most important settings arelowLatencyMode, target live delay, maximum live latency, and catch-up speed.
Recommended low-latency setup:
maxLiveSyncPlaybackRate: 1.1; reduce it to 1.05 if viewers still rebuffer during catch-up.
dash.js
Use dash.js for LL-DASH playback in browsers and apps with MSE or MMS support. Configure the target live delay, LoL+ catch-up mode, buffer threshold, and drift handling before callinginitialize().
Recommended low-latency setup for dash.js 5.1.1:
streaming.delay.liveDelay value overrides the manifest target when useSuggestedPresentationDelay is false. Use liveDelay: 4 as a stable default; use 3 only when ingest timing and last-mile networks are stable.
If playback is far behind live and stalls repeatedly, seek to the live target instead of relying on catch-up speed alone:
liveEdge - targetDelay instead of repeatedly buffering while staying far behind live.
Device and OS support
Protocol support varies by device type and operating system version.iOS and iPadOS
LL-HLS is natively supported from iOS 14 and tvOS 14, including Safari and AVPlayer. Earlier versions fall back to standard HLS and cannot achieve true low latency. LL-DASH is supported on iOS 17.1+ through Managed Media Source (MMS), which dash.js supports. iPadOS 13+ also supports MSE (Media Source Extensions), enabling LL-DASH through JS players on iPad. Protocol support by iOS version:- iOS 17.1+ with MMS support: LL-DASH with approximately 2-second low latency.
- iOS 14.0+ with LL-HLS support: LL-HLS with approximately 3-second low latency.
- Earlier iOS versions: standard HLS (MPEG-TS) with approximately 9-second latency.