DevOps Peach

System Design for DevOps · Design a System: Three Worked Cases · Lesson 3 of 3

Design a Video Streaming Website

A video site ingests large uploads, transcodes them into several resolutions and short segments for adaptive bitrate streaming (HLS/DASH), and delivers segments from CDNs; metadata, search and view counts run on separate paths.

Practice interactively →

Video is the extreme case of "large objects, huge read volume". Almost all cost and complexity sit in transcoding and delivery.

flowchart LR
  UP["Creator upload (multipart)"] --> RAW["Object storage: raw"]
  RAW --> JOB["Transcode queue"]
  JOB --> TX["Transcoders: 240p … 1080p, 6 s segments"]
  TX --> OUT["Object storage: HLS/DASH"]
  OUT --> CDN["CDN (multi-CDN)"]
  CDN --> P["Player: picks bitrate per segment"]
  META["Metadata, search, views"] -.-> P
  %% step UP: Large files are uploaded in parts, resumable, directly to object storage.
  %% step JOB: A job per video goes to a queue; transcoding is slow and expensive, so it is asynchronous.
  %% step TX: Transcoders produce several resolutions, each cut into short segments, plus a playlist.
  %% step OUT: Segments and playlists are stored as ordinary objects.
  %% step CDN: The CDN serves segments from the edge — this is most of the traffic.
  %% step P: The player measures bandwidth and switches quality segment by segment (adaptive bitrate).
  %% step META: Titles, search and view counts are separate services and databases.

1–2. Requirements and estimates

Upload videos, watch with fast start and few rebuffers, search, view counts. 5 M daily viewers × 30 min at ~3 Mbit/s average: peak concurrency 500 k viewers × 3 Mbit/s ≈ 1.5 Tbit/s — only a CDN (or several) can carry that. 50,000 uploads/day × 1 GB raw → 50 TB/day before transcoding.

3. Adaptive bitrate streaming

Each video becomes a ladder of renditions (e.g. 240p 400 kbit/s … 1080p 5 Mbit/s), each split into 2–6 s segments, with a manifest (master.m3u8 for HLS, .mpd for DASH). The player starts low for a fast start, then climbs as bandwidth allows and drops instead of stalling.

4. Data model

videos(video_id, owner_id, title, status, duration, renditions, created_at), search index (Elasticsearch/OpenSearch), view counts as events → stream → aggregated counters (never UPDATE views = views + 1 per view on one row).

5. Key choices

Choice Why
Multipart, resumable uploads to storage Multi-GB files over mobile networks
Queue + autoscaled transcoders (spot instances) Work is bursty, parallel per segment and interruptible
Managed transcoding (MediaConvert, Transcoder API) or FFmpeg on Kubernetes Trade cost against control
Segments with long TTLs; manifests with short TTLs Segments never change; playlists may (live)
Multi-CDN with steering by quality Capacity, resilience and price at this scale
Signed URLs/cookies, DRM for premium content Stop hot-linking and piracy

6. Bottlenecks

Transcoding backlog after a viral upload event → scale on queue depth; prioritise short or popular videos. Cold content → keep popular renditions on the CDN, older ones in cheaper storage tiers. Start time → small first segments and pre-warming popular titles. View count hot spots → sharded counters.

Traps: serving video from application servers; one huge MP4 instead of segments; transcoding synchronously on upload; counting views with a single-row update.

Practice interactively →