Design Video Streaming (YouTube/Netflix)
Case Study: Design Video Streaming
Section titled “Case Study: Design Video Streaming”A video streaming platform like YouTube or Netflix allows users to upload, process, and watch videos.
Requirements
Section titled “Requirements”Functional:
- Upload videos
- Transcode videos to multiple resolutions (240p, 480p, 720p, 1080p, 4K)
- Stream videos with adaptive bitrate
- Search videos
Non-functional:
- Low latency streaming (< 2s startup)
- Support 500M DAU
- 500 hours of video uploaded per minute
Estimation
Section titled “Estimation”| Metric | Value |
|---|---|
| Video uploads/minute | 500 hours |
| Storage per minute | 500 hours × 1 GB/hour = 500 GB/min |
| Storage per day | 500 GB × 60 × 24 = 720 TB/day |
| CDN bandwidth | 100M concurrent viewers × 5 Mbps = 500 Tbps |
High-Level Design
Section titled “High-Level Design”flowchart LR Upload["📤 Upload"] --> LB["Load Balancer"] LB --> App["Web Server"] App --> Queue["Transcoding Queue"] Queue --> Transcoder["🎬 Transcoder Farm"] Transcoder --> Storage[("Object Store<br/>S3/Blob")] Transcoder --> Meta[("Metadata DB<br/>PostgreSQL")]
Playback["📱 Playback"] --> CDN["🌐 CDN"] CDN --> Storage
style Upload fill:#7c3aed,color:#fff style App fill:#4f46e5,color:#fff style Queue fill:#6366f1,color:#fff style Transcoder fill:#8b5cf6,color:#fff style Storage fill:#059669,color:#fff style CDN fill:#059669,color:#fffDeep Dive: Transcoding Pipeline
Section titled “Deep Dive: Transcoding Pipeline”// Upload flow1. User uploads video → stored as original in blob storage2. Upload event → message queue → transcoder workers pick it up3. Transcode to multiple resolutions (240p, 480p, 720p, 1080p)4. Generate thumbnails at key frames5. Store transcoded segments + manifest file (.m3u8 for HLS)6. Update metadata DB with processing statusWhy transcode? Different devices need different resolutions. Adaptive bitrate lets the player switch quality based on network conditions.
Deep Dive: Adaptive Bitrate Streaming (HLS)
Section titled “Deep Dive: Adaptive Bitrate Streaming (HLS)”manifest.m3u8├── 240p.m3u8 → segment001.ts, segment002.ts, ...├── 480p.m3u8 → segment001.ts, segment002.ts, ...├── 720p.m3u8 → segment001.ts, segment002.ts, ...└── 1080p.m3u8 → segment001.ts, segment002.ts, ...Video is split into segments (2-10 seconds each). The player dynamically switches between quality levels based on bandwidth.
Deep Dive: CDN Strategy
Section titled “Deep Dive: CDN Strategy”- Popular videos — cached at CDN edge for instant playback
- Long-tail videos — served from origin if less popular
- Pre-fetching — CDN pre-warms cache based on trending predictions
Bottlenecks & Trade-offs
Section titled “Bottlenecks & Trade-offs”| Bottleneck | Solution |
|---|---|
| Storage costs | Store hot data on fast SSDs, cold data on archival storage |
| Transcoding delay | Queue-based async processing, parallel transcoding |
| CDN costs | Cache popular content, use a tiered CDN strategy |
| Global latency | Regional CDN edge nodes, anycast DNS |
Follow-up Questions
Section titled “Follow-up Questions”Q: A video suddenly goes viral overnight — how does the CDN keep up? The origin would get hammered if every edge node had a cache miss at once. Use predictive pre-warming (push the video to more edge PoPs as view velocity spikes) and let the CDN’s own request-collapsing merge concurrent cache-miss requests into one origin fetch instead of one per viewer.
Q: How do you pick the adaptive bitrate ladder for mobile vs desktop? Mobile players default to lower rungs (240p-480p) to conserve data and battery, and the manifest can expose a mobile-specific subset of the ladder. Desktop/TV clients get the full ladder up to 4K since bandwidth and screen size justify it — the ladder itself is defined once at transcode time, the player just picks which rungs to advertise.
Q: What happens if transcoding fails partway through a large upload? Transcoding runs per-resolution as independent jobs, so a failure in the 1080p job shouldn’t block 240p/480p from being available. Each job is retried with exponential backoff, and the metadata DB tracks per-resolution status so the video can go “live” with whatever resolutions succeeded while failed ones retry in the background.
Q: How do you avoid re-transcoding the same content uploaded by multiple users (e.g., reposted clips)? Hash the uploaded file (or use perceptual/content hashing) before transcoding and check against already-processed content. If it matches, just point the new video record at the existing transcoded segments instead of burning transcoder capacity again.
Q: How do you keep playback smooth when a user’s network quality fluctuates mid-stream? The player measures recent segment download throughput and buffer health, then switches to a lower/higher rung on the next segment boundary — never mid-segment. Segments are short (2-10s) specifically so this switch is fast and doesn’t require re-buffering from scratch.
In Simple Words
Section titled “In Simple Words”- Video streaming = upload → transcode (convert to multiple formats) → store → deliver via CDN.
- Adaptive bitrate (HLS) splits video into small segments so the player can switch quality on the fly.
- CDN is critical — without it, every viewer would hit the origin server (impossible at scale).