Sweaty Imposter

Design YouTube / Video Streaming

System DesignMediaRead HeavySenior3 min readUpdated

Uploads are slow and heavy, and views are huge and global. The interview is about the asynchronous transcoding pipeline and pushing nearly every byte of playback out to the CDN.

1 · Requirements

The Prompt

Design video upload, transcoding, and global streaming for 1B+ daily views.

Functional

  • Upload large videos, resuming after a dropped connection
  • Transcode each upload into several resolutions
  • Stream with adaptive bitrate on any device
  • Count views and show basic stats

Non-Functional

  • Playback starts quickly and adapts to the viewer's bandwidth
  • An upload is never lost once the client sees it complete
  • The origin serves only a small share of video bytes

2 · Estimates

Drill This Phase First

Show the Answer and Estimates

Answer

About 50 TB a day

500,000 times 100 MB is 50 TB a day, or about 18 PB a year before transcoding multiplies it about 5x.

Ingest
500,000 uploads a day at about 100 MB: 50 TB a day raw, about 18 PB a year before transcoding
Renditions
About 6 renditions from 240p to 4K multiply storage about 5x: roughly 250 TB a day after encoding
Egress
1B views a day at about 10 MB streamed: 10 PB a day. The CDN absorbs over 95%, so the origin serves under 500 TB
Streams
About 35,000 stream starts a second at a 3x peak, with about 5M viewers watching at once
Metadata
About 1B videos at 2 KB each: roughly 2 TB in SQL, sharded by video_id
Encoders
Transcoding 50 TB a day takes about 30,000 vCPUs sustained, autoscaled on queue depth

3 · API

POST /uploads/init { filename, size, mime } → { upload_id, chunk_urls[] }
PUT /uploads/:id/chunks/:n (resumable) → 200
POST /uploads/:id/complete → { video_id, status: processing }
GET /videos/:id → { manifest_url, title, channel, stats }
GET /watch/:id/manifest.m3u8 → HLS playlist (signed, served by the CDN)
POST /videos/:id/view → 202 (async to counter pipeline)

Data Model

videos (SQL, sharded by video_id):
  video_id (PK)   : uuid
  uploader_id     : uuid
  title, desc     : string
  duration_s      : int
  status          : enum(uploading|processing|ready|failed)
  created_at      : timestamp

renditions (SQL):
  video_id (FK)   : uuid
  resolution      : enum(240p|360p|...|2160p)
  codec           : string
  s3_key          : string
  bitrate_kbps    : int

view_counts (wide-column, partition = video_id, cluster = bucket_hour):
  video_id        : uuid
  bucket_hour     : timestamp
  views           : counter

4 · High-Level Design

The write path is asynchronous: upload, store the raw file, queue a job, transcode, and store the renditions. The read path is mostly the CDN: the API returns a signed manifest, and the player pulls segments from the nearest edge.

5 · Deep Dives

Resumable Uploads

Split the file into chunks, each with its own pre-signed URL, and track which chunks have landed. After a dropped connection the client asks for the missing chunk numbers and sends only those. Completion is one call that checks every chunk and queues the transcode job.

Transcoding Pipeline

Cut each video into segments a few seconds long and transcode them in parallel across workers, so a long upload finishes in minutes. A job names its video and rendition, and a retry overwrites the same output key, so a crashed worker leaves nothing half written.

Adaptive Bitrate and the CDN

HLS and DASH manifests list every rendition, and the player switches between them as bandwidth changes. Popular videos stay warm at the edge. Long-tail videos fall back to a regional cache and then the origin, which is where most of the remaining egress cost sits.

6 · Wrap Up

Name the next risks: view count fraud, copyright matching on upload, and storage cost for long-tail videos that almost nobody watches.

The Short Version

Upload to object storage, queue a job, have transcoder workers encode multiple bitrates, and serve them through a CDN. Metadata in SQL; view counts in wide-column. Adaptive bitrate (HLS/DASH).