System Design (High-Level Design) Module 15 – Files, objects and media
Media pipelines: transcoding and adaptive bitrate
Design an upload-to-playback pipeline for video and images: transcode a bitrate ladder, package HLS and DASH segments, and let players adapt to the network.
What you will learn
- Design an upload-to-playback pipeline for images and video as queued, retryable jobs
- Calculate the storage and the CDN egress of a bitrate ladder
- Write HLS playlists and check them against the rules of RFC 8216
- Choose rungs and segment durations for an audience and a budget
- Compare throughput-based and buffer-based rung choices on stalls and bit rate
Before you start
What you’ll learn · Before you start
What you will learn
- Design an upload-to-playback pipeline for images and video as queued, retryable jobs
- Calculate the storage and the CDN egress of a bitrate ladder
- Write HLS playlists and check them against the rules of RFC 8216
- Choose rungs and segment durations for an audience and a budget
- Compare throughput-based and buffer-based rung choices on stalls and bit rate
Before you start
On this page
One minute of video becomes 192 MB once it is encoded into the nine renditions of Apple’s example ladder, and a viewer on its default rung pulls 900 MB an hour from the CDN. A video pipeline turns one upload into those files: it validates the upload, Decoding a video and encoding it again in another format, resolution or bit rate, as the pipeline does once for every rung of the ladder. it into a ladder of renditions, each a resolution and a bit rate, cuts every rendition into short segments listed in playlists, and publishes them through a CDN.
The player then measures how fast each segment downloads and picks the rung for the next one, so a viewer on a weak phone connection and one on home fibre watch the same video at different qualities without stalling. Each stage is a queued job that can fail and be retried, and images follow the same idea with a few sizes and modern formats.
A pipeline turns one upload into a ladder of renditions
From upload to adaptive playback
Text description of the diagram
The diagram runs from top to bottom.
- The original upload sits in object storage.
- A job from a queue validates and probes it: its real type, duration and codecs.
- The transcoder makes one rendition per rung of the ladder, for example 360p, 720p and 1080p, as separate jobs.
- The packager cuts each rendition into short segments and writes the playlists or manifests for HLS and DASH.
- The packaged files are published to a CDN, which caches the segments.
- The player fetches segments over HTTP and picks a rung for each segment from its measured network speed and its buffer.
Read the diagram as a chain of independent jobs. Probing rejects files that are not what they claim before any expensive work starts. Each rung transcodes separately, so a slow 1080p job never delays the 360p rendition that weak connections need first. And the packager writes segments that never change, which the CDN can cache for as long as the video exists. Follow one upload down the chain:
The drawing shows the whole scene; its 6 steps are listed below.
Every step as text
- The original lands. A 3-minute upload lands in object storage. The pipeline keeps the original, so that a new format or a new rung can be made from it later.
- Probe before any heavy work. A job reads the file's real type, duration and codecs. A file that is not what it claims is rejected here, before any expensive transcoding starts.
- One job per rung. The transcoder makes one rendition for every rung of the ladder, as separate jobs, so a slow 1080p job never delays the 360p rendition that weak connections need first.
- Cut into segments. The packager cuts each rendition into short segments of a few seconds each, and writes the playlists that list them.
- Publish once. The segments never change, so the CDN can cache them for as long as the video exists.
- The player adapts. The player measures how fast each segment downloads and picks the rung of the next one, lower when the network slows and higher when it recovers.
The bitrate ladder: The set of renditions a video is encoded into, each a resolution and a bit rate, from which a player picks the rung its network can sustain. decides most of the cost. Apple’s HLS authoring specification gives an example H.264 ladder of nine rungs, from 416×234 at 145 kbit/s to 1920×1080 at 7,800 kbit/s, and recommends the 2,000 kbit/s rung as the default variant (HLS authoring specification). Every rung is a full copy of the video, so storage adds up across the ladder:
# What a bitrate ladder costs to store, using the example H.264 ladder of Apple's HLS authoring specification (16:9,
# average bit rates in kbit/s). Every rung is a full copy of the video, so the storage adds up across the ladder.
LADDER = [
("416x234", 145), ("640x360", 365), ("768x432", 730), ("768x432", 1100), ("960x540", 2000),
("1280x720", 3000), ("1280x720", 4500), ("1920x1080", 6000), ("1920x1080", 7800),
]
def mb_per_minute(kbps):
return kbps * 1000 * 60 / 8 / 10**6 # kilobits a second -> megabytes a minute
print(f"{'rung':<12}{'kbit/s':>8}{'MB per minute':>15}")
for size, kbps in LADDER:
print(f"{size:<12}{kbps:>8,}{mb_per_minute(kbps):>15.1f}")
total = sum(mb_per_minute(k) for _, k in LADDER)
print(f"{'all rungs':<12}{sum(k for _, k in LADDER):>8,}{total:>15.1f}")
print(f"\nA 10-minute upload stored in every rung: {total * 10 / 1000:.2f} GB")
print(f"A library of 100,000 hours: {total * 60 * 100_000 / 10**6:,.0f} TB")
print(f"One viewer on the 2,000 kbit/s rung uses {mb_per_minute(2000) * 60:,.0f} MB an hour; on the top rung {mb_per_minute(7800) * 60:,.0f} MB") Output
rung kbit/s MB per minute 416x234 145 1.1 640x360 365 2.7 768x432 730 5.5 768x432 1,100 8.2 960x540 2,000 15.0 1280x720 3,000 22.5 1280x720 4,500 33.8 1920x1080 6,000 45.0 1920x1080 7,800 58.5 all rungs 25,640 192.3 A 10-minute upload stored in every rung: 1.92 GB A library of 100,000 hours: 1,154 TB One viewer on the 2,000 kbit/s rung uses 900 MB an hour; on the top rung 3,510 MB
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 ladder.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
One minute of video becomes 192 MB in nine renditions, and a viewer of the default rung pulls 900 MB an hour from the CDN. Those two numbers, storage per minute and egress per viewing hour, are what the ladder trades against quality.
A few more terms complete the picture, each in one sentence. HLS, defined in RFC 8216, lists media segments in playlists that players fetch over plain HTTP (RFC 8216). MPEG-DASH does the same with an XML manifest and is standardised as ISO/IEC 23009-1. CMAF is a segment format that HLS and DASH can share, which DASH-IF’s guidelines build on (DASH-IF). The segment duration sets how often a player can switch rungs and how far a live stream lags. adaptive bitrate: Streaming in which the player picks the rendition of each next segment from what it measures, such as recent download rates or the seconds already buffered. logic in the player chooses the rung for each segment, from recent download rates, from the seconds of video already buffered, or from both. A ladder is fitted to the audience’s networks, and a job that keeps failing goes to a dead-letter queue. Images get the same treatment with a few sizes in formats such as WebP.
Checkpoint
Check: The pipeline and its ladder
Designing a ladder for an audience, with numbers Pro: opens with a Pro, Premium or Ultimate pass
In this part:
- Segments and playlists, written and checked
- Every stage is a queued, retryable job, sized by Little’s law
- How players choose a rung, simulated
- Images need a few sizes in modern formats
- Practise: size a ladder and its playlists
- Size a bitrate ladder and the playlists that serve it
- Interview questions
- What is adaptive bitrate streaming, and why do video services use it?
- Design the pipeline that takes 500,000 video uploads a day, averaging 3 minutes each, from upload to adaptive playback for viewers worldwide. Size the transcoding fleet and the storage.
- Choose the segment duration and the key-frame interval for a video-on-demand library and for a live sports stream. Defend each choice with numbers.
- Viewers on mobile networks stall far more often than everyone else on your video service. Find the cause and fix it in the ladder and in the player.
- Key takeaways
1 diagram · 4 runnable examples (Python) · 1 exercise with sample tests · 3 interview answers · about 39 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
Terms in this lesson
- adaptive bitrate
- Streaming in which the player picks the rendition of each next segment from what it measures, such as recent download rates or the seconds already buffered.
- bitrate ladder
- The set of renditions a video is encoded into, each a resolution and a bit rate, from which a player picks the rung its network can sustain.
References
- RFC 8216: HTTP Live Streaming (IETF)
- HTTP Live Streaming 2nd Edition (draft-pantos-hls-rfc8216bis) (IETF)
- HLS authoring specification for Apple devices (Apple)
- DASH-IF implementation guidelines (Interoperability Points) (DASH Industry Forum)
- FFmpeg formats documentation (hls muxer) (FFmpeg project)
- A buffer-based approach to rate adaptation (ACM SIGCOMM 2014) (ACM)
- An image format for the Web (WebP) (Google)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress