ABR Streaming
Back to blog
HLS

Building the Bitrate Ladder: From Fixed Rungs to Per-Title Encoding

How to design an encoding ladder — resolution/bitrate rungs, the Apple reference ladder, convex-hull and per-title encoding, and device considerations.

ABR Streaming Team5 min read
Bitrate LadderEncodingPer-TitleConvex HullVMAF

The bitrate ladder is the set of renditions a player can switch between, and it is the single biggest lever on both your streaming quality and your CDN bill. Get it right and viewers see crisp video that adapts smoothly; get it wrong and you either burn bandwidth on rungs nobody benefits from or strand viewers in a quality cliff. This article is about designing the ladder — a complement to the ABR overview, which covers how players climb one. To see a real ladder parsed from a manifest, use the player's manifest inspector; to inspect the codec and bitrate of a source file, use the media info tool.

What a rung is

Each rung is a complete encode at a chosen resolution and bitrate. In the master playlist it becomes one #EXT-X-STREAM-INF variant:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5400000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
v1080/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
v720/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=854x480,CODECS="avc1.64001e,mp4a.40.2"
v480/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=730000,RESOLUTION=640x360,CODECS="avc1.640015,mp4a.40.2"
v360/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=365000,RESOLUTION=416x234,CODECS="avc1.640015,mp4a.40.2"
v234/index.m3u8

Design rules for a fixed ladder

A static ladder is a reasonable starting point and still common for live. Two rules dominate:

  1. Adjacent rungs should be roughly 1.5–2x apart in bitrate. Closer together and you pay storage and CDN cost for switches viewers never notice; further apart and every switch is a jarring jump that ABR logic will hesitate to make.
  2. The bottom rung must be reliably deliverable. It is what keeps a struggling connection playing instead of buffering, and it is often where the player starts before it has measured throughput. Make it small and robust.

A few more practical considerations:

  • Resolution should track bitrate. Encoding 1080p at 800 Kbps looks worse than encoding 480p at 800 Kbps, because the codec spends bits it does not have on resolution it cannot afford. Each rung should sit at the resolution that looks best for its bitrate.
  • Cap the top rung to your audience. A 16 Mbps 4K rung is wasted if your viewers are on phones and the content is not 4K to begin with.

The classic industry ladder

Apple's HLS authoring guidance has long published a reference H.264 ladder that many pipelines started from. The exact numbers shift between revisions and should be treated as approximate, but the shape is consistent:

  • 416x234 around 145 Kbps (audio-priority floor)
  • 640x360 around 365 Kbps
  • 768x432 around 730 Kbps
  • 768x432 around 1.1 Mbps
  • 960x540 around 2.0 Mbps
  • 1280x720 around 3.0 Mbps
  • 1280x720 around 4.5 Mbps
  • 1920x1080 around 6.0 Mbps
  • 1920x1080 around 7.8 Mbps

Note that some resolutions appear at two bitrates — the ladder oversamples around the resolutions where most viewing happens. These are reasonable defaults, but a fixed ladder treats every title the same, which is where the savings are left on the table.

Per-title and convex-hull encoding

A flat news desk and a high-motion sports clip have wildly different complexity, yet a fixed ladder encodes both identically. Per-title encoding fixes this by analyzing each asset and producing a custom ladder.

The core technique is the convex hull. For each candidate resolution you encode the title at several bitrates and measure quality (typically with VMAF, covered in Video Quality Metrics). Plot quality against bitrate for all resolutions, and the upper envelope — the convex hull — tells you, for any given bitrate, which resolution gives the best quality. Your ladder rungs are the points on that hull. The practical results:

  • Low-complexity content gets fewer or lower-bitrate rungs while looking just as good, saving storage and bandwidth.
  • High-complexity content gets the bits it actually needs at each rung.
  • Each rung switches to a higher resolution exactly at the bitrate where doing so starts to help.

Context-aware encoding

The next step beyond per-title is context-aware (or per-shot) encoding: analyze complexity within a title — shot by shot or scene by scene — and even vary the segment-level encode, plus account for the viewing context (device, typical network, screen size). A two-pass or shot-detected encode lets a single rendition allocate more bits to a complex action scene and fewer to a static dialogue scene, holding quality steady across the whole title rather than across the whole catalog.

Device and network considerations

The ladder is not just a quality-vs-bitrate curve; it has to land on real hardware:

  • Decoder support. Old TVs and STBs may not decode HEVC or AV1, and many cap at certain H.264 levels (resolution × frame rate). Your CODECS strings must be honest about the level so players can reject what they cannot play.
  • Frame rate. A 60 fps rung costs meaningfully more than 30 fps; only include high-fps rungs where the content and devices justify it.
  • Network distribution. If your analytics show most viewers between 1.5 and 4 Mbps, concentrate rungs there rather than spending the ladder on a 12 Mbps rung few can reach.
  • Codec choice moves the whole curve. HEVC, AV1, or VVC shift the quality-bitrate curve down roughly 30–50% at equal quality (approximate, and content-dependent), letting you either cut bitrate at every rung or add higher rungs at the same cost.

An example per-title-style ladder

For a moderately complex H.264 title, a tuned ladder might look like:

  • 1920x1080 @ ~4.5 Mbps (capped; complex titles would go higher)
  • 1280x720 @ ~2.4 Mbps
  • 960x540 @ ~1.4 Mbps
  • 640x360 @ ~730 Kbps
  • 416x234 @ ~300 Kbps

Treat every number as approximate and content-dependent — the point of per-title encoding is that there is no universal answer.

Validate before you ship

Build the ladder, then check it: confirm the rungs, resolutions, and codec strings in the manifest inspector, verify the source file's properties with media info, and measure each rung's quality with the methods in the next article. A ladder is a hypothesis about your content and audience — measure it, then iterate.

Try it yourself

Reading about streaming is one thing — pull apart a real manifest, play a stream, and measure its QoE with the toolkit.

Browse all tools