Chapter 14 · System Design Fundamentals
Design YouTube
A video platform is many systems wearing one trench coat. The trick is to split it: a light control plane for titles, comments and view counts, and a heavy blob plane that turns one raw upload into dozens of adaptive streams and pushes them through storage tiers and a global CDN. Read-heavy, write-light, and planet-scale.
▶ Open the companion slidesStrip the product to its two verbs — upload and watch — and the asymmetry jumps out. A handful of creators push in enormous files; a billion viewers pull small chunks back out. So the whole design bends toward reads: the write path is an expensive, one-time factory that manufactures cheap, cache-friendly artifacts, and the read path is a hierarchy of caches that keeps origin storage from ever seeing the crowd.
Alex Xu, System Design Interview (Vol. 1), Chapter 14. Companion deck:
slides — jump to any slide with the
Slide N chips. Go deeper: the
HTTP Live Streaming spec (RFC 8216),
which defines the .m3u8 manifests every player reads.
What we are actually building Slide 2
Pin the scope before drawing boxes. The functional surface is small — upload a file, watch it on any device, and a thin layer of social state around it. The hard requirements are non-functional, and one number decides the architecture: reads outnumber writes by roughly two orders of magnitude. That single fact is why the read path gets a CDN and the write path gets a factory.
Functional
Creators upload from web or mobile. Viewers watch on phones, laptops, TVs and slow links. Comments, likes and subscriptions. Search and "up next". Live streaming, monetisation and copyright matching are out of scope — each is its own design.
Non-functional
Billions of registered viewers, hundreds of millions daily. Playback start under ~2 s at p95. Eleven nines of durability on the stored masters. And graceful degradation: a comment or search outage must never stop a video from playing.
The workload has a distinctive shape: a tiny set of recent, popular videos drives almost all bandwidth (the hot tail), while the enormous back-catalogue, watched rarely, dominates storage cost (the long tail). The two pull in opposite directions, and the storage design has to serve both.
How big is "big" here? Slide 3
A back-of-the-envelope pass (the method from Chapter 2) sets the order of magnitude the architecture must respect. These are sizing sketches, not benchmarks — the point is the shape, not the digits.
of which the CDN absorbs > 95% → origin serves only the misses
Two takeaways drive everything downstream. First, storage grows with hours of video and never shrinks, so bytes must move to cheaper tiers as they cool. Second, egress is so large that it cannot come from the origin — a CDN with a very high hit ratio is not an optimisation here, it is the only way the numbers close.
High-level architecture — two planes Slide 4
Read the diagram as two independent lanes. The blob plane (top) is the video factory: an upload lands a raw master, a transcoder fans it into renditions, and the CDN serves those to viewers. The control plane (bottom) is a normal web backend: an API over a metadata database, plus an async pipeline for counts. The only thing joining them is a key — a metadata row stores the object path, never the bytes.
Upload flow — chunked, resumable, idempotent Slide 5
An hour of 4K is gigabytes crossing flaky hotel Wi-Fi. Treat the upload as many small commitments, not one big bet. The client splits the file into parts, sends each straight to object storage, and on any failure asks "which offsets did you already get?" so it re-sends only the gaps. Nothing goes through the API tier's memory — it just hands out signed URLs and tracks a cursor.
Keying every part by (uploadId, partNumber) makes re-sends harmless: uploading the same
part twice overwrites identically, and the final commit is a single atomic stitch. A
duplicate commit is a no-op, so a client that times out and retries can never create two
videos or a half-written one.
Transcoding pipeline as a DAG Slide 6
The master is probed, split on GOP boundaries, and fanned out to many encoders that run in parallel — one per resolution-and-codec target — plus side jobs for thumbnails and captions. A packager wraps the outputs into HLS/DASH segments and manifests, and a final step flips the "ready" flag. Model it as a directed acyclic graph of pure, retryable jobs: each node is a function of its inputs, so a lost output is simply rebuilt, and encoders scale out horizontally.
One source, many renditions Slide 7
Why manufacture so many copies? Because a flagship phone on fibre and a five-year-old tablet on café Wi-Fi cannot use the same file. The transcoder builds a bitrate ladder — the same content at rising resolutions and bitrates, in several codecs — and the player picks the highest rung it can currently afford. Newer codecs (AV1, VP9) cut bytes 30–50% over H.264 but cost more CPU to decode, so shipping multiple codecs lets each device choose its own trade-off.
| Rendition | Bitrate | Who it serves |
|---|---|---|
| 2160p · AV1 | ~16 Mbps | Big screens on fast, stable links; modern decoders only. |
| 1080p · H.264 | ~5 Mbps | The safe default — decodes everywhere, good on broadband. |
| 720p · H.264 | ~2.5 Mbps | Mobile on decent cellular; the common fallback rung. |
| 480p / 360p | ~1 / 0.5 Mbps | Congested or metered networks; keeps playback alive. |
| 240p · H.264 | ~0.2 Mbps | The floor. Ugly but watchable when the link collapses. |
Renditions are derived data: they can always be rebuilt from the master. That is why we pay eleven-nines durability only on the source, and can freely re-encode the long tail into cheaper codecs later to shrink its footprint.
Hot, warm, cold — long tail to deep archive Slide 8
A tiny slice of videos earns almost all views in their first week; everything else becomes long-tail, watched rarely but kept forever. The cost equation only closes if bytes move to match their access pattern. An access-frequency tracker promotes and demotes objects across tiers asynchronously, so a viewer never blocks on a tier migration — a cold read just takes a beat longer.
| Tier | Where | Serves | Read latency |
|---|---|---|---|
| Hot | SSD/RAM at the edge | Trending, last 24 h | sub-ms |
| Warm | Regional object store | Popular renditions | < 100 ms |
| Cold | Multi-region, erasure-coded | Long-tail watches | seconds |
| Archive | Deep/glacial storage | Masters & rare originals | minutes |
The master lives in archive at top-tier durability; the renditions people actually watch flow up toward the edge on demand. Because renditions are rebuildable, a cold tier can trade some availability for cost without ever risking the source.
HLS & DASH — manifests over plain HTTP Slide 9
We never stream one giant file. Each rendition is sliced into short segments (2–6
seconds), and a manifest tells the player where every segment lives. A master manifest
lists the available renditions; each rendition has its own playlist of segment URLs. Everything is a
plain HTTP GET of a static object — so it caches cleanly at every layer and rides existing
CDN machinery for free.
HLS uses .m3u8; DASH uses .mpd. They differ in syntax, not shape — both expose
a master manifest pointing at per-rendition playlists — so a modern packager emits both side by side.
Adaptive bitrate selection — the player decides Slide 10
Quality is not chosen by the server — it is chosen on the device, segment by segment. The server just publishes the menu (the manifest); the client orders whatever fits its current appetite. That is deliberate: only the device sees real-time radio strength, contention and throttling, and only it can react inside a single 6-second segment.
Signals it watches
Times each segment download for a rolling bandwidth estimate; watches its own playback buffer (a draining buffer means "drop quality now"); and folds in device hints — screen size, decoder load, battery.
Why hysteresis
It adds a deadband so it does not flap up and down on every wobble. Ramp up cautiously when the buffer is healthy; drop fast when it is starving. Smoothness beats chasing the last megabit.
CDN — edge POPs, mid-tier shield, origin Slide 11
A three-layer cache hierarchy puts bytes seconds away from every viewer while protecting the origin from the herd. Viewers hit a nearby edge POP; on a miss the edge asks a regional origin shield; only if the shield also misses does the origin get touched. The shield's job is request collapsing: when a new video goes viral, a thousand edge misses for the same segment become one origin fetch.
Metadata and blobs live apart Slide 12
Titles, comments, subscriptions and view counts are small and reached by rich queries; video bytes are huge and reached by primary key alone. Mixing them is the fastest route to a crashed database. So the metadata plane is an indexed, transactional, cached store (the key-value / NoSQL and sharded-SQL patterns from earlier chapters), while the blob plane is flat, immutable, key-only object storage. The link between them is just a path string.
Failure isolation falls out for free: a metadata outage might hide a title or comment thread, but the CDN keeps feeding segments to every in-flight watch. And swapping the blob backend later becomes a one-column migration, because the row never held bytes — only a pointer.
View counts — async aggregation Slide 13
A trending video can take a million plays a minute. Writing one row per view into a relational table would incinerate the database — and it is the wrong model anyway. Counts are eventually-consistent metrics, not transactions. Play events stream through a log into a real-time aggregator that feeds a fast, approximate live counter, while a slower batch reconciler recomputes the authoritative number, stripping bots and duplicates.
Six principles Slide 14
Split the byte plane from the control plane
Metadata and blobs scale and fail on different curves. Glue them with a key, not a join.
Heavy work is a DAG of small, retryable jobs
Transcoding, packaging and reconciliation are idempotent steps that can be rebuilt on demand.
Push intelligence to the edges
The CDN absorbs the bytes, the player picks the quality, the origin only sees the misses that survive both.
Move bytes with their access pattern
Hot at the edge, warm regionally, cold and archived below. Pay top-tier durability only on the master.
Counts are streams, not transactions
Views, likes and trending are async aggregates. Show a fast approximation now, reconcile the truth later.
No component takes the watch down with it
Comments, recommendations, search may fail — playback must keep rolling. Design every dependency to be sheddable.
Active recall
Cover the answers. Say each one out loud before you tap to check.
(uploadId, partNumber). On retry the client asks which offsets landed and re-sends only
gaps; a re-sent part overwrites identically and a duplicate commit is a no-op.Check yourself
(uploadId, partNumber)?