Design a Video Streaming Platform (YouTube / Netflix)
The largest-scale case study there is. Transcoding pipelines, HLS and DASH, why 95%+ of bytes must never touch your origin, and counting views at a billion a day.
Covers: Upload and transcoding pipeline, adaptive bitrate streaming, CDN strategy, storage tiering, view counting
Video is the case study where estimation genuinely decides the architecture. The bandwidth numbers are so large that they rule out entire designs immediately, and the whole system is organised around one goal: almost no byte of video should ever come from your own servers.
- Scale: 500 hours uploaded per minute; 1 B hours watched per day.
- Upload storage: at ~1 GB/hour source, 500 h/min × 60 × 24 ≈ 720 TB/day of source video, before transcoding.
- Transcoded output: roughly 3–5× the source across renditions, so 2–4 PB/day.
- Egress: 1 B hours/day at ~3 Mbps average ≈ 1.35 exabytes/day, or ~125 Tbps sustained. No origin can serve this - the CDN is not an optimisation, it is the system.
30-second answer
Upload directly to object storage with a pre-signed URL so the bytes never pass through your application servers, using resumable multipart upload for reliability on poor connections. Then split the source into short segments - typically 5 to 30 seconds - and transcode segments in parallel across a worker fleet, which turns a two-hour serial job into a few minutes of wall-clock time. Each segment is encoded into every rendition, then the outputs are stitched into HLS and DASH manifests. The pipeline is a DAG of retryable stages with per-segment idempotency, because at this volume individual task failures are constant.
Upload and transcode pipeline
Segment-parallel transcoding is the key idea: the job is embarrassingly parallel, so wall-clock time is a function of fleet size rather than video length.
Flow
- Client uploadRaw storage
- Raw storageSplitter
- SplitterTranscode fleet
- Transcode fleetManifest builder
- Manifest builderCDN
| Rendition | Resolution | Bitrate | Audience |
|---|---|---|---|
| 240p | 426×240 | ~0.3 Mbps | Very poor connections |
| 480p | 854×480 | ~1 Mbps | Mobile on cellular |
| 720p | 1280×720 | ~2.5 Mbps | Default for most |
| 1080p | 1920×1080 | ~5 Mbps | Desktop, good connection |
| 4K | 3840×2160 | ~15–25 Mbps | Premium tier |
Every rendition multiplies storage and transcode cost. Generate the top renditions lazily for long-tail content: most videos are never watched in 4K.
Say these points
- Pre-signed direct-to-object-storage upload keeps bytes off your servers.
- Split at keyframes and transcode segments in parallel - wall clock becomes fleet-size-bound.
- Keyframe alignment across renditions enables seamless bitrate switching.
- Every task is idempotent and retryable, so spot instances are viable.
- Transcode high renditions lazily based on popularity.
Avoid these mistakes
- Uploading through the application tier.
- Serial transcoding of whole files.
- Generating every rendition for every upload regardless of demand.
- Segments not keyframe-aligned, breaking adaptive switching.
Expect these follow-ups
- A transcode job fails at segment 400 of 720. What happens?
- How do you handle a live stream rather than an uploaded file?
- How would you roll out a new, more efficient codec to an existing library?
30-second answer
The player fetches a master manifest listing every available rendition, then requests short segments one at a time. It measures throughput and buffer level and switches rendition between segments, so quality adapts to changing network conditions without interrupting playback. On distribution, essentially all bytes must come from CDN edges: pre-position popular content, use origin shielding for the long tail, and for the very largest platforms place caching appliances directly inside ISP networks so traffic never crosses the public internet at all.
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=300000,RESOLUTION=426x240,CODECS="avc1.42e00a,mp4a.40.2"
240p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=854x480,CODECS="avc1.4d401e,mp4a.40.2"
480p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8
# And within 720p/index.m3u8 - the segment list the player actually fetches:
#EXTINF:10.0,
seg_00001.ts
#EXTINF:10.0,
seg_00002.ts1 · Start conservatively
Begin at a low rendition so playback starts fast. Startup time is the metric users judge most harshly - a two-second delay measurably increases abandonment.2 · Measure and adapt
After each segment the player knows how long it took, and therefore the effective throughput. Combined with buffer level it decides whether to step up, hold, or step down for the next segment.3 · Buffer defensively
Keep 20–30 seconds buffered. The buffer is what absorbs a temporary network dip without a visible stall, and it is why ABR can afford to be optimistic about stepping up.4 · Switch at segment boundaries
Because segments are keyframe-aligned across renditions, the decoder can start a new segment at a different bitrate seamlessly. This is the reason keyframe alignment mattered during transcoding.
Serving 125 Tbps
| Layer | Share of traffic | Mechanism |
|---|---|---|
| ISP-embedded appliances | ~60–90% | Caching servers inside ISP networks; traffic never crosses transit |
| CDN edge PoPs | ~10–35% | Standard edge caching with long TTLs |
| Regional shield | ~1–5% | Absorbs edge misses so origin sees one request per region |
| Origin | < 1% | Cold long-tail content only |
The design goal is that origin egress is a rounding error. Everything else is an implementation detail of achieving that.
Counting views at a billion a day
- Never increment a database row per view. At 1 billion views/day that is a write-hot row per popular video and a guaranteed bottleneck.
- Emit an event to a stream, aggregate in windows, and write rollups every few seconds. The displayed count is eventually consistent, which nobody notices.
- Define what counts as a view - typically 30 seconds watched, or a percentage of duration - and enforce it server-side, because client-reported views are trivially forged.
- Deduplicate per user per video within a window to resist inflation.
- Approximate the display count for very large numbers: '2.4M views' does not need exactness, so HyperLogLog or sampled counting is entirely sufficient.
Say these points
- ABR: master manifest, short segments, switch between segments using buffer level.
- Keyframe alignment across renditions is what makes switching seamless.
- Origin must serve under 1% of bytes; ISP-embedded caches carry the majority.
- Cache hit rate is bimodal - the long tail always misses, so shield the origin.
- Count views via a stream and rollups, never a per-view database increment.
Avoid these mistakes
- Serving video from application servers.
- Throughput-only ABR causing visible quality oscillation.
- Incrementing a counter row per view.
- Assuming a uniform cache hit rate across the catalogue.
- Trusting client-reported view events.
Expect these follow-ups
- How would you support live streaming with under 5 seconds of latency?
- How do you implement DRM without destroying cacheability?
- How would you personalise the homepage without breaking edge caching?
Showing 2 of 2 questions for design-a-video-streaming-platform.
Check your understanding
4 questions · no sign-up, nothing stored
Hands-on challenge
Build it - this is what you talk about in a deep-dive round.
Design the transcode and delivery pipeline
Handle 500 hours of upload per minute and 1 billion watch-hours per day, with explicit cost awareness.
Requirements
- Design the upload path with pre-signed resumable uploads and describe failure handling.
- Specify segment length and justify it against transcode parallelism and ABR switching granularity.
- Define the rendition ladder and the popularity-based lazy-transcoding policy.
- Design the CDN strategy with explicit hit-rate assumptions for head and long-tail content.
- Design view counting including the definition of a view, deduplication and the rollup interval.
Stretch goals
- Add live streaming with sub-5-second latency and explain what changes.
- Estimate the monthly cost of transcoding and egress, and identify the two biggest savings.