Video streaming: what to ask and how big it is
Part of the free System Design course on LogicWiz, in the chapter: Design video streaming. The interactive whiteboard exercises and simulations run in the app.
Week 15: Design video streaming
"I said we would keep the movie file on a server and send it to the phone. Then Kabir asked what happens when five million people press play on a train."
Meera, after her first mock interview
Start by asking, not drawing
Kabir plays the interviewer. He says one line: "Design a video streaming service." Meera grabs the marker and draws a server and a database. Kabir stops her. "You have not asked me anything yet."
A strong candidate spends the first five minutes on questions. These change the design:
- Who puts videos in? Creators uploading from phones, or a studio adding licensed films? We pick creators, about ten minutes per video.
- Is it live or on demand? Live means the video is being filmed right now, like a cricket final. On demand means a library people watch any time. We pick on demand.
- Which devices? Phones, TVs and browsers, on networks from weak 4G to home fibre.
- How soon must a new upload play? Minutes, not hours.
- Ads, offline downloads, copy protection, recommendations? We park these as follow-ups.
The live question matters most. A live stream is made seconds ago and watched by everyone at the same moment. Nothing can be prepared early, and delay is the enemy. An on-demand video exists long before anyone watches it. We can process it for minutes, store it for years and let caches keep copies near viewers for days. That freedom shapes the whole design.
Requirements, with numbers
Functional (what users can do):
- A creator uploads a video and can resume if the connection drops.
- The service turns it into versions that a phone, a TV or a browser can play.
- A viewer browses a catalogue, opens a video and watches it.
- Playback resumes where the viewer stopped, on any device.
Non-functional (how well it must work):
- 50 million viewers a day, each watching about 1 hour.
- Playback starts in under 2 seconds for 9 in 10 plays.
- Stalls (the picture freezing to load more) take under 1% of watch time.
- Playback is available 99.95% of the time. An upload may be a little less available.
- 100,000 hours of new video are uploaded each day, and no original is ever lost.
Out of scope for now: live streaming, recommendations, search, copy protection and thumbnails. Lesson 3 returns to them.
Sizing the viewing side: delivery is the big number
Work through the viewers first.
- 50 million viewers x 1 hour = 50 million viewer-hours a day.
- Spread over 24 hours, about 50M / 24 = 2 million are watching at any moment.
- Evenings are busier. Assume a peak about 2.5 times the average: about 5 million at once.
- A video's bitrate is how many bits of video it uses per second. Assume 3 Mbps on average: phones lower, TVs higher. Mbps means megabits per second, and Tbps means terabits per second: 1 Tbps is a million Mbps.
- Peak bandwidth leaving the system: 5 million x 3 Mbps = 15 million Mbps = 15 Tbps.
- Network speeds count bits, and file sizes count bytes. There are 8 bits in a byte, hence the divide by 8. One hour at 3 Mbps is 3 x 3,600 / 8 = 1,350 MB, or 1.35 GB. So 50 million hours is about 70 PB a day (67.5 PB). A petabyte, PB, is a thousand terabytes, TB, or a million GB.
At an assumed price of 1 cent per GB, that is 67.5 million GB x $0.01, about $675,000 a day. Real prices differ and big buyers pay less. The point is the size: delivery is the largest running cost, and it grows with every extra viewer.
The player fetches the video in short pieces of 6 seconds each. So 5 million viewers / 6 seconds = about 830,000 piece requests per second at peak. Each piece at 3 Mbps is 3 x 6 / 8 = 2.25 MB. Check: 830,000 x 2.25 MB is about 1.9 TB per second, which is 15 Tbps. The numbers agree.
The small calls matter less. They peak sharper than viewing, because a video lasts an hour while a page view lasts seconds, so we use three times the average. Each viewer opens about 20 catalogue pages a day: 50M x 20 = 1 billion a day, about 11,600 a second, and about 35,000 at peak. Each viewer starts about 4 videos: 200M a day, about 2,300 a second, and about 7,000 at peak.
Sizing the upload side: the pipeline
- 100,000 hours a day, at 10 minutes (one sixth of an hour) per video, is 600,000 videos a day.
- 600,000 / 86,400 seconds = about 7 uploads per second.
- An original at about 8 Mbps is 1 MB per second, or 3.6 GB an hour. So 100,000 hours x 3.6 GB = about 360 TB a day.
- We make 5 versions, called renditions: 240p at 0.4 Mbps, 360p at 0.8, 480p at 1.5, 720p at 3 and 1080p at 6. They add up to 11.7 Mbps, so one hour costs 11.7 x 3,600 / 8 = about 5.3 GB. For 100,000 hours that is about 530 TB a day.
- New storage: 360 + 530 = about 0.9 PB a day, or about 325 PB a year.
- Encoding work: assume one CPU core encodes one rendition about as fast as the video plays. Real speed depends on the codec and settings, so treat this as a planning number. 100,000 hours x 5 renditions = 500,000 core-hours a day, which is 500,000 / 24 = about 21,000 cores busy all day.
Meera's first guess was that storage is the hard part, because videos are big files. Compare the two numbers. Storage grows by 0.9 PB a day, while delivery moves 70 PB a day, about 75 times more. Storage is a real cost and it only grows, but delivery is where the volume, the bill and the speed problems live.
The API and the data model
There are two kinds of calls. Small control calls go to our servers: about 7 uploads and 7,000 play starts a second. The video bytes never go through them. They come from storage and a CDN (a network of cache servers close to viewers).
POST /videos {title, sizeBytes} -> 201 {videoId, uploadUrls}
PUT <uploadUrl> (one part of the file) -> 200 {etag}
POST /videos/{id}/complete {etags} -> 202 {status: "processing"}
GET /videos/{id} -> 200 {title, durationS, status}
GET /videos/{id}/playback -> 200 {manifestUrl, resumeSeconds}
GET <manifestUrl> -> 200 manifest (qualities and piece list)
GET <segmentUrl> -> 200 video bytes, served by the CDN
PUT /me/progress/{videoId} {positionS} -> 204
The answer 202 means "accepted, the work happens later". Processing takes minutes, so the call cannot wait.
videos(video_id PK, owner_id, title, duration_s, status, created_at)
renditions(video_id, name, bitrate_kbps, segment_count)
object keys: originals/{video_id} and v/{video_id}/{rendition}/{n}.m4s
watch_progress(user_id, video_id) -> position_s
watch_history(user_id, watched_at, video_id)
Small rows with relations (titles, owners, status) fit a database. Big files fit object storage. Progress is one overwritten number per user and video, so it fits a key-value store.
📌 Summary: Ask live or on demand first. Delivery moves about 70 PB a day against 0.9 PB of new storage, so plan for it. Control calls are small; video bytes come from a CDN.
What Meera learns next
Numbers in hand, Meera can draw. Next: the design built box by box, from one server to an upload pipeline, segments, a manifest and a CDN.
Check your understanding
- Meera says: "The files are big, so storage is the hard part." The service adds about 0.9 PB of video a day and delivers about 70 PB a day. What is the best reply?
- At the evening peak, 3 million people watch at about 4 Mbps each. How much bandwidth must the system send?
- A new platform gets 30,000 hours of uploads a day, at ten minutes per video. About how many uploads arrive each second?
- A candidate lets creators POST the whole 600 MB file to the API servers. At 7 uploads a second, what is wrong?