Segment

Streaming

The unit a streaming player downloads: a short, self-contained media file holding a few seconds of a stream, and the boundary at which adaptive bitrate switches renditions. Containers are MPEG-TS (.ts) or fragmented MP4/CMAF (.m4s, .mp4). A segment is not the stream and not its manifest.

Also known as chunk.

11 min read Updated Aug 30, 2026

Full Explanation

A segment is the unit a streaming player downloads: a short, self-contained media file holding a few seconds of a stream's audio or video. The player reads a manifest file. This is a playlist in HLS, or an MPD in DASH. As RFC 8216 section 2 puts it, the player then “downloads and plays each Media Segment declared within it”. A segment is not the stream and not the manifest. It is the addressable object the manifest points at, the object a CDN stores and counts, and the boundary where adaptive bitrate switches renditions. It is also not an fMP4 fragment. A fragment is a piece inside a segment. Informally it is called a chunk.

How it works

An encoder or a separate packager cuts the compressed stream at key-frame boundaries. This lets a decoder start on any segment without earlier data. RFC 8216, section 3 requires that “Any Media Segment that contains video SHOULD include enough information to initialize a video decoder and decode a continuous set of frames that includes the final frame in the Segment”. It adds that “any Media Segment containing H.264 video SHOULD contain an Instantaneous Decoding Refresh (IDR); frames prior to the first IDR will be downloaded but possibly discarded.” Apple's HLS authoring specification is stricter than the RFC. Requirement 7.4 is that “Video segments MUST start with an IDR frame.”

Each segment is identified by a URI and, optionally, a byte range. RFC 8216, section 3, states: “A Media Segment is specified by a URI and optionally a byte range”. The EXT-X-BYTERANGE tag “indicates that a Media Segment is a sub-range of the resource identified by its URI” (section 4.3.2.2). So several segments can live inside one file. Order matters, and the bitstream must join up. Each segment “MUST carry the continuation of the encoded bitstream from the end of the segment with the previous Media Sequence Number, where values in a series such as timestamps and Continuity Counters MUST continue uninterrupted”. The RFC warns that “Unmarked media discontinuities can trigger playback errors.”

Two container families are in use. MPEG-2 Transport Stream segments (usually .ts) need a Media Initialization Section that is “a Program Association Table (PAT) followed by a Program Map Table (PMT)” (RFC 8216, section 3.2). Fragmented MP4 segments (usually .m4s or .mp4) split the roles. As RFC 8216 puts it, “an MPEG-4 Fragment consists of a Movie Fragment Box ('moof') containing a subset of the sample table and a Media Data Box containing those samples”. Use of fragments “does require a Movie Box for initialization, but that Movie Box contains only non-sample-specific information such as track and sample descriptions” (section 3.3). The samples themselves sit in the Media Data Box, not in the moof. The initialization Movie Box is a separate object. The player fetches it once. The Common Media Application Format (CMAF) constrains that container. It is ISO/IEC 23000-19, “Common media application format (CMAF) for segmented media” (cited as [CMAF] in RFC 8216, section 11.2). RFC 8216 section 3.3 notes that a CMAF Header and a CMAF Segment meet the HLS fMP4 requirements. Akamai's CMAF requirements state that CMAF “promotes the use of the same media segments in both HLS and DASH”, with one .mpd and one .m3u8 manifest over a single set of segments.

Segment duration is a trade-off with no universal answer. Bitmovin's segment-length study summarises current practice as “Typical segment duration ranges between 2-6 seconds for VOD, balancing playback stability, adaptive bitrate (ABR) responsiveness, and CDN cache efficiency”. It concludes there is no universal best segment length. That is because the optimum depends on the use case, the latency target, and network conditions. Apple's authoring specification is concrete for its own devices. It says “Target durations SHOULD be 6 seconds” and “Segment durations SHOULD be nominally 6 seconds (for example, NTSC 29.97 may be 6.006 seconds)”. It also says “Media Segments MUST NOT exceed the target duration by more than 0.5 seconds.” Short segments start sooner, switch renditions sooner, and cut live latency. But they multiply HTTP requests, and they cost compression because holding a fixed GOP to the segment length forces more I-frames. I-frames “need more bits for encoding than predicted (P-) frames”. In Bitmovin's PSNR table, the spread from 1-second to 15-second segments is about 1.5 dB at 300 kbit/s. The study warns that segments shorter than two seconds “perform very poorly”.

At the live edge, low-latency streaming does not shorten the segment. It publishes pieces of it early. In Low-Latency HLS, Partial Segments divide the live edge “into a larger number of smaller pieces, such as CMAF Chunks”. Each Partial Segment is declared by an EXT-X-PART tag. Each carries “a subset of the media samples in its Parent Segment” (HTTP Live Streaming 2nd Edition, section 3.2). A Partial Segment may be a byte range of its parent rather than a separate file, via the BYTERANGE attribute. Apple's RECOMMENDED Part Target Duration is one second.

Why it matters for a CDN

Segments are where nearly all of a streaming service's bytes and requests are. So segment cache policy is streaming CDN policy. The manifest and the segments behave in opposite ways on the same hostname. On a live stream, the manifest is rewritten every few seconds, but its URL stays the same. A segment's bytes never change once written. That asymmetry, not the media, is what forces two cache-control policies per endpoint.

For VOD, max-age is what buys a long life. RFC 8246's immutable directive adds something narrower. It “indicates that the origin server will not update the representation of that resource during the freshness lifetime of the response”. So clients “SHOULD NOT issue a conditional request during the response's freshness lifetime (e.g., upon a reload)”. And proxies “SHOULD skip conditionally revalidating fresh responses”. It saves revalidation round trips. It does not extend the lifetime. The RFC is explicit that it “only applies during the freshness lifetime of the stored response”. Stale responses “SHOULD be revalidated as they normally would”. The guarantee also assumes the versioned-URL pattern RFC 8246 was written for. If content can change under a fixed URL, the promise is false.

Live segments are the opposite case. They are created in real time. They are worth caching only while a player might still ask for them. That period is the DVR window. Hold them longer, and the cache fills with media nobody will request. Expire them sooner, and every DVR seek becomes an origin fetch. CMAF lets one set of segments serve both packagings, so the alternative is measurable. Akamai notes that storing TS and ISOBMFF copies of the same content costs “twice as much to store on origin and compete on Akamai edge caches for space, thus reducing the delivery efficiency.”

The two rules look like this in a Cache-Control header:

# CDN caching strategy for video segments
# VOD segments: bytes never change, so skip revalidation
Cache-Control: public, max-age=86400, immutable

# Live segments: cache for the DVR window (2 hours here)
Cache-Control: public, max-age=7200

# Segment file extensions to cache aggressively:
# .m4s (fragmented MP4), .ts (MPEG-TS), .mp4

What CDNs do

  • AWS CloudFront: its MediaPackage live guide splits manifests from segments. It says, “You typically set up two cache behaviors for each endpoint: The parent manifest, which is the index to your files. The segments, which are the files of the video content.” The path patterns are extension-based (*.m3u8 or *.mpd for manifests, *.ts for HLS and *.mp4 for CMAF and DASH segments). For each of those cache behaviours, it says to set Minimum TTL “to 5 seconds or less, to help prevent serving stale content.”
  • Akamai Adaptive Media Delivery: its Live delivery mode “adjusts the TTL of the manifests if no specific caching rules are defined”. In that case, it “assigns a very short TTL to the stream manifest file so that updates to it are retrieved in a timely manner.” A Live-mode advanced option, Segment Access Time, sets a TTL for the segments themselves. The caution is that it “also applies to DVR access to your live segments. If you set too low of a TTL, this can overwhelm your origin with DVR access requests for your segments.”
  • Fastly recommends “setting manifest file TTLs to less than half of the video segment duration, typically 1-2 seconds for 5-second video segments”. It recommends far longer segment TTLs (its sample VCL uses 1s for m3u8|mpd and 3600s for aac|dash|m4s|mp4|ts). Players routinely request segments the origin has not published yet. So it also advises that error “status code responses should be made cacheable and should only be cached with TTLs small enough to give sufficient time for origins to recover (around 1s).”
  • Cloudflare caches a response when “The Cache-Control header is set to public and max-age is greater than 0”, or when Expires is in the future. It “only caches based on file extension and not by MIME type.” Its documented default extension list includes MP4 but not TS or M4S. So HLS and DASH segments generally need explicit Cache Rules rather than relying on the default set.

Watch out for

  • GOP length that does not divide the segment length. Fixed I-frame positions are what make a segment independently decodable and switchable. Bitmovin notes they are achieved “by restricting the group-of-picture (GOP) size of the encoder to the desired segment size”. Get this wrong, and players download frames they must discard. RFC 8216 section 3 warns of exactly this.
  • Renditions whose boundaries drift apart. Apple requires that “All variants and renditions MUST have discontinuities at the same points in time”. Apple also recommends that “all audio/video variants and renditions SHOULD have segment boundaries at the same points in time”. If they do not, an ABR switch cannot land cleanly on a boundary.
  • Treating short segments as free. Every halving of duration roughly doubles the request count against the CDN. Each halving also costs encoding efficiency. Bitmovin's measurements put segments under two seconds in the “perform very poorly” band.
  • Quoting a single number as the right duration. 2-6 seconds is a typical VOD range. 6 seconds is Apple's recommendation for its devices, not a universal rule. A low-latency live channel and a long-form VOD catalogue land in different places.
  • Serving live segments under VOD policy. A live segment that outlives its DVR window is dead weight in cache. A manifest cached like a segment freezes the stream.
  • Marking a segment immutable on a URL you may need to reuse. Immutable suppresses revalidation for the whole freshness lifetime. So a re-encode or a fix behind a long max-age is only reachable by purge or by a new URL.

Best practice

  • Align the encoder's GOP to the segment length. Start every video segment on an IDR frame. Place the boundaries at the same times in every rendition. This makes an ABR switch a clean cut.
  • Choose duration from content and latency target. Use 2-6 seconds for VOD, or 6 seconds if you follow Apple's authoring specification. Go shorter only when a latency budget demands it. Prefer longer segments where latency allows, for compression and for request count.
  • Publish VOD segments on versioned URLs with a long max-age. Add immutable to remove revalidation traffic. Cache live segments for about the DVR window and no longer.
  • Configure the manifest and the segments as separate cache policies, keyed on extension (.m3u8, .mpd against .ts, .m4s, .mp4). Use a short manifest TTL. Use a short TTL on error responses at the live edge.
  • Package once as CMAF. Reference the same segments from both the HLS playlist and the DASH manifest. This way, the edge caches one copy instead of two.
  • Support byte-range serving at the edge. This lets segments packed into one file, and Low-Latency HLS Partial Segments addressed by BYTERANGE, be served from cache rather than triggering full origin fetches.

Examples

A 90-minute VOD movie has about 900 six-second segments per rendition. Five quality levels make 4,500 segments in total. Each one is cached with max-age=86400. A live channel makes 10 new segments per minute per rendition. Old segments leave the cache when they exit the DVR window.

Frequently Asked Questions

The unit a streaming player downloads: a short, self-contained media file holding a few seconds of a stream, and the boundary at which adaptive bitrate switches renditions. Containers are MPEG-TS (.ts) or fragmented MP4/CMAF (.m4s, .mp4). A segment is not the stream and not its manifest.

A 90-minute VOD movie has about 900 six-second segments per rendition. Five quality levels make 4,500 segments in total. Each one is cached with max-age=86400. A live channel makes 10 new segments per minute per rendition. Old segments leave the cache when they exit the DVR window.

Yes. Segment is also known as chunk. The unit a streaming player downloads: a short, self-contained media file holding a few seconds of a stream, and the boundary at which adaptive bitrate switches renditions. Containers are MPEG-TS (.ts) or fragmented MP4/CMAF (.m4s, .mp4). A segment is not the stream and not its manifest.