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.