Media & Streaming
Design YouTube / Netflix
01
Scope
Scope
- Creators upload videos up to 12 hours or 256 GB from browsers and phones, with resume after a dropped connection.
- Every upload is converted into an adaptive bitrate ladder from 144p to 4K, plus thumbnails and auto captions.
- Viewers press play on any device and quality adjusts automatically to their connection.
- Seek to any point; resume where you left off on another device.
- Show view counts, likes and a watch history per account.
- Creators see processing status and can publish as public, unlisted or scheduled.
- Uploads are scanned for copyright matches and policy violations before or soon after publishing.
- Time to first frame under 2 seconds at p90 on a typical broadband or 4G connection.
- Rebuffering under 0.5% of watch time.
- A 10-minute 1080p upload is watchable at some quality within 3 minutes, and fully processed within 15.
- Uploaded originals are never lost: eleven nines of durability.
- Playback stays available during the loss of a region or a CDN provider.
- Delivery cost per hour watched keeps falling as the catalogue grows.
The name joins two products with very different bottlenecks. Ask early which one the interviewer means, or say you will design for user uploads and mention where a studio catalogue would differ.
- Millions of new videos a day from anyone
- Most videos are watched rarely; a few explode
- Encoding must be fast and cheap per video
- Spend expensive codecs only once a video is popular
- Moderation and copyright matching at upload time
- A few thousand titles arrive a year from studios
- Releases are known in advance, so caches are filled ahead
- Encoding can take hours per title to save bandwidth
- DRM and licensing windows per country
- Delivery appliances live inside ISP networks
02
Rough numbers
Rough numbers
Assume 800 million daily viewers who watch about 45 minutes each, and creators who upload 400 hours of video every minute. The average upload is 10 minutes long and arrives at about 10 Mbps. Delivered streams average 2.5 Mbps once you mix phones and televisions.
| Quantity | Working | Result |
|---|---|---|
| Hours uploaded per day | 400 h x 1,440 min | 576,000 h |
| Videos uploaded per day | 576,000 h x 6 per hour | about 3.5M |
| Original bytes per day | 576,000 h x 4.5 GB per hour at 10 Mbps | about 2.6 PB |
| Rendition bytes per day | H.264 ladder about 9 Mbps total plus VP9 about 5.5 Mbps, so about 6.5 GB per hour | about 3.7 PB |
| New storage per year | 6.3 PB a day x 365, before redundancy | about 2.3 EB |
| Hours watched per day | 800M x 0.75 h | 600M h |
| Views per day | 800M x 6 videos | 4.8B, about 1,400 per upload |
| Egress per day | 600M h x 1.1 GB per hour at 2.5 Mbps | about 675 PB |
| Delivery bandwidth | 675 PB x 8 / 86,400 s, peak 2x | about 62 Tbps, peak 125 Tbps |
| Encoding compute | 576,000 h x about 20 core-hours each | about 480,000 cores busy around the clock |
| Segment requests at peak | peak concurrent streams about 50M, one 4 s segment each per 4 s | about 12.5M / s |
Upload volume is large but steady, and it lands in object storage once. Delivery is two orders of magnitude bigger in bytes and has a person waiting on every request. No origin can serve 125 Tbps, so the architecture is mostly a plan for keeping segments as close to viewers as possible. The second big cost is encoding compute, which is why choosing when to spend expensive codecs matters.
03
API design
API design
04
Architecture
Architecture
flowchart LR
CR["Creator app"] --> UP["Upload service"]
UP --> RAW[("Originals bucket")]
UP -. "upload complete" .-> Q[["Job queue"]]
Q --> ORC["Pipeline orchestrator"]
ORC --> ENC["Encoder fleet"]
ENC --> REN[("Renditions bucket")]
ORC --> META[("Video metadata")]
V["Viewer player"] --> PB["Playback API"]
PB --> META
V --> EDGE["Edge cache in ISP"]
EDGE -->|miss| MID["Regional shield cache"]
MID -->|miss| REN
V -. "heartbeats" .-> AN[["Events stream"]]The write side is a pipeline. The upload service accepts parts directly into an originals bucket and, once the last part is verified against the file hash, drops a job on a queue. An orchestrator turns that job into a graph of tasks: inspect the file, split it into segments, encode each segment into each rendition, check quality, package and publish. Encoders are a large, mostly stateless fleet, much of it on cheap preemptible machines, because every task can simply be retried.
The read side barely touches our data centres. The playback API is a small service that checks permissions, picks a CDN and returns a signed manifest URL. From then on the player fetches a few kilobytes of manifest and then a steady stream of 4-second segments, almost all of them from an edge cache inside the viewer's ISP. Misses go to a regional shield that protects the origin, and only the shield ever reads the renditions bucket.
Resumable sessions with fixed-size parts. Parts land in object storage in the nearest region, so the upload is as fast as the creator's link allows and a crash loses at most one part.
Keeps the task graph per video in a durable workflow engine. It knows which segments are done, retries failures and publishes low renditions first so a video becomes playable early.
Workers pull segment tasks, encode with ffmpeg-style tooling or hardware encoders, and write output keyed by video, rendition and segment number. Identical inputs give identical outputs, so retries are safe.
Video records, rendition lists, ownership and visibility, served through a cache. View counts and likes live in a separate counter system so a viral video does not create a hot row.
Edge caches in ISPs and internet exchanges, a regional shield layer, then origin. Popular titles are pushed to edges ahead of demand; the long tail is pulled through on first request.
Heartbeats feed watch history, view counting with bot filtering, recommendations and quality monitoring that steers traffic away from a struggling CDN.
05
Deep dive: the encoding pipeline
Deep dive: the encoding pipeline
Encoding a single hour of 1080p into a full ladder in two codecs can take tens of CPU core-hours. Done as one job on one machine, a long video would take most of a day. Done carelessly at our upload rate, it would cost more than the delivery network. The pipeline has to be both parallel enough to be fast and selective enough to be cheap.
Split, encode in parallel, stitch
First the orchestrator inspects the original: duration, frame rate, resolution, audio tracks, whether it is HDR. Then it splits the video into chunks of roughly 10 seconds, cutting only at keyframes so each chunk decodes on its own. A 10-minute upload becomes 60 chunks, and each chunk becomes an independent task per output rendition. With 8 renditions that is 480 small tasks that can run on 480 machines at once, so the wall-clock time is bounded by the slowest chunk, not the length of the video.
Each encoder writes its output with forced keyframes every 2 seconds, so that every rendition has segment boundaries at exactly the same timestamps. That alignment is what lets a player switch from 720p to 1080p between two segments without a glitch. A packaging step then wraps the encoded chunks into CMAF segments of 4 seconds, which both HLS and DASH players can read, and writes one manifest per format that lists every rendition.
flowchart TD
IN["Upload verified"] --> PR["Probe: duration, codecs, HDR"]
PR --> SP["Split at keyframes into 10 s chunks"]
SP --> FAST["Encode 360p and 720p H.264 first"]
SP --> FULL["Encode 1080p and 4K H.264"]
FAST --> PK1["Package and publish: playable"]
FULL --> QC["Quality check per chunk"]
QC --> PK2["Package full ladder"]
PR --> AUX["Thumbnails, captions, audio fingerprint"]
AUX --> MOD["Copyright and policy checks"]
PK2 --> POP{"Watch time over threshold?"}
POP -->|yes| VP9["Re-encode in VP9 or AV1"]
POP -->|no| DONE["Keep H.264 only"]The ladder we produce
Every upload gets an H.264 ladder, because every device can decode it. Higher-efficiency codecs are added later and only when a video earns them.
Spend compute where viewers are
Most uploads are watched a handful of times. Encoding all of them in AV1, which costs many times more CPU than H.264, would waste most of that work. So the pipeline is tiered. Every video gets the fast H.264 ladder. Once a video passes a watch-time threshold, a second pass re-encodes it in VP9 or AV1, which cuts the bytes per hour by 30 to 50%. For the few videos with very large audiences, it is worth going further: per-title or per-scene encoding runs trial encodes at several bitrates, scores them with a perceptual metric such as VMAF, and picks the cheapest bitrate per rung that still looks right. A cartoon may need half the bits of a handheld concert video at the same resolution.
Quality checks run on every chunk before packaging. Encoders occasionally produce corrupted output, especially on preemptible machines that are reclaimed mid-write. A chunk whose duration, frame count or quality score is off is re-encoded instead of being shipped to millions of screens.
Adaptive playback
The player downloads the manifest, starts at a conservative rung so the first frame appears quickly, and measures how fast each segment arrives. It keeps a buffer of 10 to 30 seconds and moves up the ladder when throughput and buffer allow, down when the buffer drains. Because segments are aligned across rungs, switching costs nothing but the next request. Starting fast matters more than starting sharp: viewers abandon a slow start far more than a soft first few seconds.
06
Key decisions
Key decisions
Uploads return as soon as the bytes are safe. Hundreds of workers share one video, retries affect a single chunk, and the fleet can use preemptible capacity because losing a task is cheap.
Fast and cost-efficientSimpler to build, but a two-hour video takes hours to process, a crash at 90% starts over, and one machine type has to suit every file size.
Slow and fragileEach night, predicted popular titles are copied into edge caches while links are idle, so the morning's demand is served without touching the shield. Everything else is cached on first request.
Best hit rate per byteNo prediction needed and nothing wasted on titles nobody watches. But the first viewers of every hit wait for misses, and a surprise release can stampede the shield.
Fine for the long tailOne set of media files serves both Apple devices and everything else. Only the small manifests differ, so storage and cache footprint are not doubled.
Half the storage of separate packagingCommon before CMAF existed. It doubles bytes in storage and in every edge cache, and halves the effective hit rate.
WastefulEncoding cost follows watch time instead of upload volume. The first few hundred views use slightly more bandwidth, which is small next to the compute saved on millions of videos that never get those views.
Compute follows demandEvery video looks its best from the first view, at several times the encoding bill. Most of that output would sit in storage and never be requested.
Pays for unwatched videoOriginals are read only when we re-encode, so they can sit in an archive tier with erasure coding at about 1.4x overhead. Renditions of active videos stay in a hot tier close to the shields.
Durable and cheapSaves 2.6 PB a day. But every future codec, resolution or quality fix would have to start from an already compressed rendition, and quality would degrade with each generation.
Tempting, usually regretted07
Failure modes
Failure modes
A wave of preemptible instances is taken back by the cloud provider. Thousands of chunk tasks stop halfway, some after writing partial output files.
Tasks hold a lease with a heartbeat; when it lapses, the orchestrator reissues the task. Output is written to a temporary key and renamed only after a checksum, so a partial file is never treated as finished. Keep a slice of on-demand capacity for videos whose deadline is close.A creator with tens of millions of subscribers publishes. Within a minute, millions of players request the same first segments, none of which are cached at any edge yet.
Edges collapse concurrent misses into one upstream fetch, and the shield does the same, so the origin sees one request per segment per region. For scheduled premieres, push the first minutes of every rendition to edges before the publish time.A faulty encoder build produces green frames in some chunks. The pipeline publishes them and viewers see a flash of garbage at one point in the video.
Check duration, frame count and a quality score on every chunk before packaging. Canary new encoder versions on a small share of uploads, and keep enough metadata to re-encode just the affected chunks of every affected video.An edge site has a hardware fault or a congested link. Its viewers see rebuffering, but nothing on our servers is failing, so ordinary alarms stay quiet.
Use player heartbeats as the alarm: rebuffer ratio by CDN and by ISP. The playback API steers new sessions to a healthy site or a second CDN, and the manifest includes fallback hosts so active players can switch mid-stream.A video gets 200,000 views a minute and each heartbeat tries to increment one row. The shard that owns it saturates and slows down playback API calls that read the same record.
Never count on the request path. Heartbeats go to an event stream, a streaming job filters bots and aggregates counts per minute, and the metadata cache shows a value that is a few minutes old.08
Mistakes to avoid
Mistakes to avoid
Even a small platform needs terabits per second at peak. Application servers and a single region cannot carry that, and viewers far away get slow starts.
The player cannot switch quality mid-stream, seeking needs range requests that cache poorly, and a network dip stalls playback.
Waiting for 4K and the efficient codecs before anything is playable turns a three-minute wait into an hour for long videos.
09
Interview advice
Interview advice
Split the problem in two right away. Say there is an encoding pipeline and a delivery network, with different bottlenecks, and ask which the interviewer wants to explore first.
Compute egress early. Turning watch hours into terabits per second makes the CDN obviously necessary. It is the single most persuasive number in this problem.
Explain why segments are aligned. Keyframes at fixed timestamps across every rendition are what make adaptive switching seamless. Few candidates say this and interviewers notice.
Parallelise by chunk, not by video. Show how a 10-minute upload becomes hundreds of independent tasks and how a crash loses one of them, not the whole job.
Talk about cost, not only speed. Mention tiered encoding where expensive codecs follow watch time, and per-title tuning for the biggest titles.
Describe the player. Buffer targets, starting at a low rung, and measuring throughput per segment show you understand that adaptive streaming is a client algorithm.
Keep counters off the hot path. View counts and likes are a classic hot-key trap. Use an event stream and aggregation, and accept a few minutes of lag.
Mention moderation and rights. Audio and video fingerprinting before publishing, and DRM for paid catalogues, show product awareness beyond plumbing.
10
How it grows
How it grows
One worker encodes each upload into 360p, 720p and 1080p with a single command. Files are served from object storage behind a commercial CDN. Simple and perfectly adequate at this size.
Put a queue between upload and encoding, add a worker pool, and switch to segmented HLS so players can adapt. Resumable uploads arrive because long videos keep failing.
Whole-file encoding is too slow for long uploads. Split at keyframes, encode chunks in parallel, publish low renditions first and add quality checks.
Bandwidth is now the largest bill. Add VP9 and AV1 for popular videos, per-title tuning for the biggest, and place cache appliances inside ISP networks filled overnight.
Several CDNs and the in-house edge are chosen per session from live player telemetry, and the pipeline runs in multiple regions close to creators.
Watch and read
Try next
Free to read · better with landed
Whiteboard this with landed
landed runs it as a live system design round on the whiteboard and grades your trade-offs.
