What the interviewer is asking
"Design YouTube" (or Netflix) is the classic system design question about big files. Storing video is the easy part. The hard parts are turning one upload into versions that play well on any device, and the sheer amount of video going out to viewers every second.
The interviewer wants to see you find the busy path (watching, not uploading), size it with rough numbers, and notice that bandwidth drives this design. The walkthrough follows the 8 steps of the interview framework: scope, data, API, the busy path, numbers, services, scale and deep dives.
1. Scope: what version 1 must do
- Upload a video.
- Watch it smoothly on any device and connection: a TV on fast home internet, a phone on a train.
- See its title and view count.
Name the rest and park it: comments, recommendations, live streaming, ads and paying creators. Live streaming especially is a different pipeline: there's no finished file to prepare ahead.
2. Data: a small record and a lot of bytes
The video record is a small row in a metadata database:
field example
owner ana
title Lisbon
status uploading → processing → ready
length 10 min
views added in batches
manifest v42/manifest
The bytes are objects in object storage, each under its own key: the original upload (v42/original, about 1 GB), the manifest (the list of every rendition's segments) and the segments. Each video is stored in 5 renditions, from 1080p down to 240p, each cut into 10-second segments: v42/1080p/001, v42/480p/017 and so on. A 10-minute video has 60 segments per rendition, 300 in all. The record says where the bytes are; it never holds them.
Views aren't written one by one: they're counted in the background and added to the record in batches.
3. The API: two calls
POST /videos {: "Lisbon"}
→ 201 Created {: "v42", : "<signed URL>"}
PUT URL the file, in 5 MB chunks
GET /videos/v42
→ 200 OK {: "Lisbon", : …, : "<URL>"}
The upload never passes through your servers. POST /videos creates the record (status: uploading) and answers with a signed URL: permission to write one key, v42/original, for a short time. The app sends the file straight to storage in chunks, so a dropped connection resumes instead of starting over at 900 MB. Never put storage credentials in the app: anyone who unpacks it could delete every video.
Watching starts with GET /videos/v42: the record and the manifest's address.
4. The busy path: pressing play
A video is uploaded once and watched again and again, so watching is the path to make fast:
- The player sends
GET /videos/v42to the metadata service. - The service reads the record and answers: title, views, manifest URL.
- The player downloads the manifest.
- It downloads segment 1 and starts playing.
- While segment 1 plays, it downloads segments 2, 3, 4 and on.
One read of a few hundred bytes, then segment after segment: a 5-minute watch is 30 segments of 10 seconds.
5. The numbers
Numbers from the interviewer: 1 billion views a day, each watched for about 5 minutes at about 5 Mbps, and 1 million uploads a day, about 10 minutes each. A day has 86,400 seconds; round it to 100,000 for quick math.
what working result
views starting 1 billion ÷ 100,000 s 10,000 a second
watching at once 10,000 a second × 300 s 3 million
video out 3 million × 5 Mbps 15 Tbps (17 with 86,400)
busy hours 5 × 15 Tbps 75 Tbps
uploads 1 million ÷ 100,000 s 10 a second
one video stored 10 min, all 5 renditions about 800 MB
new video a day 1 million × 800 MB 800 TB (2.4 PB in 3 copies)
Two common slips: 10,000 starts × 5 Mbps = 50 Gbps treats every view as lasting one second; 1 billion × 5 Mbps = 5,000 Tbps plays every view at the same moment.
The 800 MB comes from the bitrates: 5 + 3 + 1.5 + 0.8 + 0.4 Mbps for 600 seconds. With copies, storage grows by almost 900 PB a year. But about 190 PB go out to viewers every day (15 Tbps × 100,000 s), about 80 times what goes into storage: each video is stored once and streamed about 1,000 times. Bandwidth is the cost to design for.
For scale, YouTube has said more than 500 hours of video are uploaded every minute, about 4 times these numbers. The method is the same.
6. Services: an upload pipeline and a watch path
Making the renditions, transcoding, takes minutes of hard work per video, and 10 new videos arrive every second. It can't happen inside a request:
- Upload service: creates the record and signs upload URLs; it never touches the bytes.
- Object storage: holds originals, segments and manifests. When an upload lands, it raises an event that puts a job on the transcode queue (status: processing).
- Workers: take jobs when they're free, write the renditions back to storage, then the manifest, and set the status to ready. A crashed worker's job goes back on the queue.
- Metadata service: answers
GET /videos/{id}.
Transcoding inside the upload request would leave the creator waiting for minutes; transcoding when the first viewer presses play would make every early viewer wait.
7. Scale: a CDN for the bytes, a cache for the records
If every segment comes out of storage in one data center, that's 15 Tbps from one place. One server's network sends about 1 GB a second (8 Gbps), so 15,000 Gbps is about 2,000 servers' worth, and viewers on other continents wait about 150 ms per request. Put a CDN in front: edges near the viewers fetch a segment on its first miss and hand the same copy to everyone nearby. Segments never change once made: the ideal case for a CDN.
Every view also starts with one GET /videos/{id}: 10,000 a second, about 50,000 at busy hours, 10 times what one database server answers (about 5,000 lookups a second). A cache keeps the records of videos being watched in memory; one cache server answers about 100,000 lookups a second. Views reach the record in batches anyway, so a cached count a minute old is fine.
8. Deep dive: transcoding in parallel
Say one machine makes one rendition of a 10-minute video in about 10 minutes: all 5 take it 50 minutes. One worker per rendition still takes 10 minutes, and a machine twice as fast takes 25.
Instead, cut the video at the 10-second marks and make every segment of every rendition its own job: 60 segments × 5 renditions = 300 independent jobs, taken off the queue by many workers at once. A crash loses one 10-second job. A 1-minute clip (6 segments, 30 jobs) on 10 workers, 10 seconds a job:
time being made jobs done
0 s segments 1 and 2 (W1–W10) 0
10 s segments 3 and 4 10
20 s segments 5 and 6 20
30 s nothing left 30, then the manifest
30 seconds instead of 300. For v42, 300 jobs on 20 workers take 15 rounds: 150 s instead of 50 minutes. Cutting every rendition at the same marks also lets the player switch renditions at any segment boundary. And it's where the upload side spends its money: 3,000 worker-seconds per video, 10 videos a second, about 30,000 workers busy on average.
9. Deep dive: adaptive bitrate streaming
Ana watches on a TV on fast internet; Ben on a phone on a train, where his speed swings between 8 and 2 Mbps. Any one fixed rendition fails one of them, so the player chooses again for every segment: adaptive bitrate streaming, with HLS and DASH as the common formats.
rendition needs
1080p 5 Mbps
720p 3 Mbps
480p 1.5 Mbps
360p 0.8 Mbps
240p 0.4 Mbps
A simple rule: pick the highest rendition that needs at most 80% of the speed measured on the last segment. Ben's player keeps about 30 seconds downloaded ahead, and his train leaves the city a minute in:
segment picked from rendition arrives in buffer
7 to 9 8 Mbps (6.4) 1080p 6.25 s kept at 30 s
10 8 Mbps (6.4) 1080p 25 s 30 → 5 → 15 s
11 2 Mbps (1.6) 480p 7.5 s 15 → 7.5 → 17.5 s
12 2 Mbps (1.6) 480p 7.5 s 17.5 → 10 → 20 s
Segment 10 was picked before the drop: its 50 Mb take 25 seconds while 25 seconds of video play, so the buffer falls to 5 seconds but never empties. Then the player steps down to 480p, which arrives faster than it plays, and the buffer grows back. 720p would have been a mistake: 15 seconds per segment of 10, dry during the second one. When the speed comes back, the player steps back up. Real players also watch how full the buffer is, and start low so the video starts fast.
10. Deep dive: popular videos and the long tail
Views follow a long tail: say the top 10% of videos get 90% of the views. An edge can't hold the whole library, so it keeps what people near it are watching; the least watched are dropped. About 90% of views are hits from a tenth of the library, and storage sends only the tail: about 1.5 Tbps instead of 15. Keeping every video everywhere would take 9 times more room for the last 10% of views.
A premiere is the exception. When a hit series releases at 8 pm, every edge misses at once: say 1,000 edges × 5 renditions is up to 5,000 requests for each segment within seconds. For big releases at a known time, push the files to the edges in the quiet hours before (a longer TTL wouldn't help: it only keeps copies an edge already has). Netflix has described filling its own servers inside internet providers' networks ahead of time, during quiet hours.
What breaks first
- A viral video: many edges missing at once can flood storage; a middle layer of regional caches helps.
- A file that never transcodes: after a few retries, a dead-letter queue, and the status says it failed.
- The view count: one write per view on a hot video's row would melt it; count views apart.
Summary: the order to follow
- Scope: upload, watch smoothly anywhere, title and views.
- Data: a small record; the original, the manifest and every segment in object storage.
- API:
POST /videoswith a signed upload URL,GET /videos/{id}with a manifest URL. - Busy path: watching: one record, then segment after segment.
- Numbers: about 15 Tbps out, 800 TB of new video a day.
- Services: upload service, transcode queue and workers, metadata service.
- Scale: a CDN for the segments, a cache for the records.
- Transcoding: 300 small jobs at once, 150 s instead of 50 minutes.
- Adaptive streaming: each segment's rendition from the measured speed.
- Popular videos: kept at the edges; premieres pushed ahead.
The same steps work for any "design X" question: scope, data, API, the busy path and its numbers, services, scale, then the deep dives the interviewer cares about.