SwadhyAI Notes

All System Design notes

System Design Case Study

Video Streaming

You open YouTube or Netflix, tap play, and expect the first frames within a couple of seconds, even on a crowded train Wi‑Fi. Somewhere else, a creator just uploaded a long video and sees "processing" for minutes. Both actions feel like one product, but they are two different systems.

Good video design separates async upload and from latency-sensitive playback over a with . Your API should never stream gigabytes per viewer.

What happens first?

1

Upload + ingest

Resumable bytes land in object storage.

2

Workers build many qualities in parallel.

3

Publish playlists only after QC passes.

4

+

Viewer fetches segments; quality adapts.

Try it: video streaming CDN and origin path

Play starts at the edge. Cache misses pull segments from origin; adaptive bitrate changes which object key the player requests.

  1. Player
  2. CDN edge
  3. Origin packager
  4. Object store
  5. License / DRM
Highlighted hops show where the last action moved traffic. A stopped hop means backpressure, rejection, or a consistency guard blocked further progress on that path.
Edge hits
0
Origin pulls
0
Mode
vod
Path hop
0

Capacity

egress

0 segment requests, 0 origin pulls.

Latency

startup

VOD leans on long-lived CDN caching.

Failure

origin

If origin is down, only warm CDN segments remain playable until TTL expires.

Choose VOD or live, then fetch segments to watch edge hits versus origin pulls.

What actually happens

The creator's app opens an upload session, receives , and sends chunks straight to object storage. When the upload finishes, ingest validates the object and publishes a durable event on . The HTTP response returns quickly with status processing: not "ready to watch."

Transcode workers then turn one master file into many renditions and package them as or segments. Only after quality checks pass does the catalog publish a . When a viewer taps play, the streaming API returns a signed manifest URL; the player pulls segments from the nearest edge and uses to pick the next quality.

At HLD scale: roughly 1.5B users, 800M DAU, and 500 hours uploaded per minute: the goals stay simple to say and hard to keep: sub-2s startup, low rebuffer, durable storage, and optional DRM for premium tiers. Playback traffic must not share fate with the transcode queue.

How to choose the shape of the system

1. Is this upload or playback? Upload can take minutes and retry safely. Playback needs the first segment fast. Never make the player wait on transcode workers or recommendation jobs.

2. Where should the bytes live? Put raw and transcoded objects in cheap object storage. Put the catalog, status, and entitlement checks in services the API can answer quickly. Let the own segment delivery.

3. What happens when a video goes viral? Design for cache hits and an . If every edge misses at once, origin egress, not your streaming API: is the real bottleneck.

Simple rule of thumb

Build two paths. The creator path is async: upload → event → → publish . The viewer path is thin: auth → signed playlist → segments with . Watch beacons and recommendations stay off the critical path.

In simple terms: do not stream the movie through your app servers. Stream a short playlist, then let the edge deliver the film.

Related building blocks

CDN, object storage, queues, and autoscaling dominate this design.

High-level design diagram

Follow the orange upload pipeline and blue delivery path in the drawing.

Video streaming HLD: clients through DNS CDN WAF API gateway auth, upload ingest Kafka transcode packaging QC, S3 storage catalog search, streaming API manifest CDN origin shield ABR playback, microservices analytics ads observability
Upload path

Creator → ingest → transcode

Playback path

Viewer → manifest → CDN segments

Async event

Kafka pipelines and analytics

Storage

S3/GCS raw + transcoded objects

Edge delivery

CDN + origin shield

Design highlights (from the diagram)

Upload lands in raw storage; runs async afterward.
Many renditions package as or DASH segments.
plus protect origin during spikes.
playback: from the API, bytes from the edge.
Catalog and metadata stay separate from blob storage.
Signed URLs for access; DRM is optional for premium catalogs.

Architecture layer by layer

Seven blocks mapped to the numbered HLD sections.

01
Clients, DNS, CDN, and security

Reach users globally; protect origin from abuse.

In plain terms: Highway on-ramps and toll booths before the studio lot.

Web, mobile, TV, and console clients first need a reachable endpoint and a compatible playback experience. DNS and edge routing choose an appropriate serving location, while the CDN caches application assets and reusable media segments. TLS protects each network hop; an edge that terminates it can see plaintext and must protect its own keys, logs, and connection to the origin.

WAF rules, bot defenses, and rate limits keep abusive traffic away from expensive origin paths. The gateway authenticates API calls and routes upload, catalog, and playback requests to their owners. Access to a particular video still depends on visibility and entitlement checks; a valid login token alone does not grant access to every media object.

02
Upload and ingestion

Creators upload huge files; processing starts async.

In plain terms: Drop off raw film reels at the warehouse loading dock.

The upload API creates a session and returns scoped, expiring URLs for direct multipart transfer to object storage. The client retries missing parts rather than resending the whole file. Completion verifies that the final raw object is durable and consistent with the session before recording upload success; the creator can then see processing without holding an HTTP connection open for encoding.

Ingestion validates the file and extracts metadata, with scanning and unsupported-format outcomes recorded explicitly. The catalog owns title, tags, visibility, and processing status independently of the byte object. A durable upload-completed event, commonly keyed by video ID, notifies the job orchestrator; Kafka carries that event, while the orchestrator owns stage dependencies, retries, and workflow recovery.

Upload completes when bytes land in raw storage. The creator sees "processing" until finishes, not when the upload HTTP call returns.

03
Transcoding and packaging

Turn one master file into many qualities and segment files.

In plain terms: Film lab that prints IMAX, standard, and mobile cuts from one negative.

The orchestrator records jobs for the chosen resolution and codec ladder, such as H.264, H.265, or AV1 outputs from mobile sizes through 4K where supported. Separate workers execute those jobs with bounded parallelism, and priority queues allocate capacity to time-sensitive uploads. A retry uses the same job identity and output version so two workers cannot publish conflicting results.

Packaging turns encoded media into HLS playlists and segments or a DASH manifest and its segment references. Quality checks validate duration, audio/video synchronization, required outputs, and other product criteria such as unexpected black frames. Write and validate the immutable media objects first, then atomically publish the catalog pointer to the usable manifest. A partial encode must remain processing or failed rather than expose a broken playlist.

Scale workers from queued video minutes, encoding cost, and the oldest job age; reserve a bounded share for premieres. Output must be durable and validated before publishing the . Recovery retries use the same workflow and output version rather than creating duplicate competing encodes.

04
Storage and catalog

Bytes in object store; searchable metadata in databases.

In plain terms: Warehouse shelves for tapes plus a card catalog desk.

Object storage holds raw masters, encoded segments, thumbnails, preview sprites, and captions. The catalog stores searchable facts and references: ownership, processing state, channel, available renditions, manifest version, and entitlement rules. Keeping bytes separate from metadata makes catalog transactions small and allows different lifecycle policies for originals, published media, and temporary failed outputs.

A search index projects titles, tags, and permitted transcript content for discovery; its lag does not make an existing playable object disappear. Replication and geographic placement should follow recovery and delivery requirements rather than automatically copying every asset everywhere. Retain a clear deletion workflow across catalog, derived indexes, cached access, and object versions so removing a video also removes its usable serving paths.

05
Streaming and CDN delivery

Playback is read-heavy; segments come from the edge.

In plain terms: Netflix mailer replaced by a vending machine on every block.

The streaming API checks identity, visibility, and entitlement, then returns a manifest URL with the appropriate access contract. The manifest describes compatible codecs, bitrates, and segment locations; the player ultimately chooses a rendition using device support, measured throughput, and buffer health. Seeking translates a playback time into segment requests rather than asking an application server to retransmit the entire file.

CDN edges serve those reusable segment bytes, with an origin shield coalescing misses before they reach object storage. Adaptive bitrate changes quality as conditions change, ideally avoiding a stall by reducing requested bitrate before the buffer empties. Measure startup delay and rebuffering from the player, because a fast manifest API does not prove that later segment downloads are healthy.

Viewers fetch segments from the CDN, not your API servers. Use so viral videos do not melt origin.

06
Product services (off hot path)

Comments, likes, subs, recommendations: async where possible.

In plain terms: Ticket booth, gift shop, and suggestion wall beside the theater.

User profiles, subscriptions, playlists, and watch-later lists are separate product services; comments, likes, and notifications can use durable asynchronous side effects. Search and recommendations combine offline models with fresher behavioral features. Keep those optional enrichments outside routine segment fetches so a ranking outage can produce a simpler browsing experience while an already authorized video continues playing.

Advertising and billing require an explicit product contract. VAST or VMAP may describe ad responses and schedules, while entitlement and payment systems decide access. Some services may skip an unavailable optional ad; others may pause playback or require a valid ad decision. Bound those dependencies and provide a defined fallback rather than universally asserting that monetization must always fail open.

07
Analytics, observability, and DR

Watch startup time and rebuffer, not just upload QPS.

In plain terms: Security cameras and box-office reports for the whole chain.

Player events flow through a durable stream into aggregation, warehouse, and machine-learning consumers. They report plays, progress, errors, buffering, and quality choices, but telemetry must have bounded resource use so it does not compete with playback. Track startup latency, rebuffer ratio, CDN and shield hit rates, segment failures, origin egress, and transcode queue age as separate symptoms.

Carry upload-session and job IDs through ingestion, encoding, validation, and manifest publication so a stuck video can be traced end to end. Recovery must restore both media bytes and catalog references, including access keys and processing state. Replicate or back up according to loss and recovery objectives, then test serving from the recovery location; active-active deployment alone does not prove those dependencies are independent.

Creator path vs viewer path

Async processing can take minutes. Playback must feel instant.

Creator path: durable upload, then processing

The client uploads parts directly into raw object storage, retries missing parts, and completes the session only after the final object is verified. The creator then sees processing while turns that master into compatible qualities and codecs. Upload durability and readiness for playback are different milestones, so expose both in the status API.

carries the completion event to a durable orchestrator that owns the processing graph, retry state, and priorities. Workers encode and package output, validate required segments, and publish the only when its referenced objects are usable. If one stage fails, retry that job identity or show a recoverable failure instead of making viewers discover a broken playlist.

Viewer path: bounded startup and continuous playback

After authentication and entitlement checks, the stream API returns a location. The player uses it to fetch short segments from an appropriate edge. Reusable bytes bypass application servers, while origin shielding reduces simultaneous cache-miss traffic to object storage.

chooses quality from supported renditions using measured network throughput and buffer level. Lowering bitrate can preserve uninterrupted playback on a slower connection. Watch beacons report startup, buffering, and errors asynchronously; their retries and storage should not consume the resources needed to play the next segment. Access and monetization failures follow the product’s explicitly defined playback policy.

End-to-end flows

Matches section 13 data flow on the diagram.

Upload and transcode

The upload API creates a resumable session and the client transfers bytes directly to object storage in parts. After all parts are verified, a durable completion record schedules validation and encoding. The creator sees processing until required outputs are ready. Reusing the session and part identifiers makes a network retry upload only missing data instead of starting the whole video again.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    autonumber
    participant C as Creator app
    participant GW as API gateway
    participant IN as Ingest API
    participant S3 as Raw object storage
    participant K as Kafka
    participant OR as Transcode orchestrator
    participant W as Transcode workers
    participant OUT as Transcoded storage

    C->>GW: POST upload session
    GW->>IN: presigned multipart URLs
    C->>S3: upload chunks (direct)
    C->>IN: POST upload complete
    IN->>S3: finalize object
    IN->>K: upload-completed
    IN-->>C: status processing
    K->>OR: start workflow
    OR->>W: jobs per resolution
    W->>OUT: HLS/DASH segments + manifest
    W->>K: transcode-completed
    Note over C: Poll until status ready

Transcode DAG (parallel renditions)

1080p worker

720p worker

480p worker

IngestOrchestrateParallel workersPackage / publish

Playback (ABR)

The playback API verifies access and returns a manifest location. The player reads that playlist and requests short encoded segments from the CDN, rather than streaming the entire video through the application server. Segment duration trades request overhead and caching efficiency against startup and adaptation speed. Version immutable segments so cache entries cannot mix bytes from two different encodes.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    autonumber
    participant V as Viewer app
    participant GW as API gateway
    participant ST as Streaming API
    participant CDN as CDN edge
    participant OS as Origin / S3

    V->>GW: GET /videos/{id}/stream
    GW->>ST: auth + entitlement
    ST-->>V: signed manifest URL
    V->>CDN: GET master.m3u8
    CDN-->>V: variant playlists
    loop every ~6s segment
        V->>CDN: GET segment.ts
        alt cache hit
            CDN-->>V: segment bytes
        else cache miss
            CDN->>OS: fetch segment
            OS-->>CDN: segment
            CDN-->>V: segment bytes
        end
    end
    V-->>V: ABR picks next quality

Watch events pipeline

Player beacons report startup time, playback progress, buffering, errors, and selected quality. These measurements reveal user experience that an API success rate cannot: the manifest can load successfully while every later segment stalls. Batch and send beacons asynchronously with bounded retries so telemetry does not compete with playback. Record the sampling policy because missing or delayed beacons can bias quality metrics.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    autonumber
    participant P as Player
    participant B as Beacon API
    participant K as Watch-events stream
    participant A as Analytics worker
    participant FS as Feature store
    participant RK as Ranker

    P->>B: watch heartbeat (position, quality)
    B->>K: watch-event (async)
    Note over P: playback continues: non-blocking
    K->>A: consume events
    A->>FS: update user/video features
    FS->>RK: feature lookup
    RK->>RK: recompute recommendations

What users experience

1

Creator uploads

You: You pick a video file and hit publish.

System: Resumable upload to S3 → ingest validates → Kafka starts transcode. You see "processing" for minutes, not seconds.

2

Viewer watches

You: You tap play; video starts without long buffering.

System: API returns manifest URL → player fetches HLS/DASH segments from nearest CDN; ABR adjusts quality to your Wi‑Fi.

3

Video goes viral

You: Millions watch the same clip at once.

System: CDN cache warming + origin shield absorb spike. Transcode already done: playback does not touch ingest API.

Requirements

Upload

  • Resumable chunked upload
  • Metadata and privacy
  • Virus scan / validation

Transcode & stream

  • Multi-resolution H.264/AV1
  • HLS or DASH ABR
  • Seek and quality switch

Product (off hot path)

  • Search and recommendations
  • Comments, likes, subscriptions
  • Ads / premium DRM optional

Numbers that drive the design

500 h/min
Upload volume

720K hours/day; ~3.24 PB/day ingest

1.67M/s
Segment QPS (est.)

10M viewers ÷ 6s segments

99%
CDN hit target

~16.7K origin QPS at 99% hit

<2s
Startup target

Manifest + first segment from edge

Assume 500 hours/min upload at 10 Mbps raw (~3.24 PB/day ingest), 10M concurrent viewers at 3 Mbps (~30 Tbps egress), and 6-second segments (1.67M segment QPS). Transcode needs ~90K core-equivalents at 3× real-time. Target 99% CDN hit so origin serves ~16.7K segment QPS, not millions directly.

Case-study upgrade

Video Streaming Capacity Math

Video streaming separates upload, processing, storage, and playback. Upload is asynchronous and compute-heavy; playback is read-heavy and latency-sensitive.

Assumptions and formulas

  • Upload volume: 500 hours/minute. Average raw bitrate: 10 Mbps. Average playback bitrate: 3 Mbps.
  • Playback uses 6-second segments and Content Delivery Network (CDN) edge caching.
  • Encoded variants and manifests are stored separately from raw uploads.

Concrete math

  • Upload: 500 hours/minute = 720K hours/day. At 10 Mbps raw, ingest is about 3.24 PB/day.
  • Variant storage: encoded ladder totals 2x-4x mezzanine size depending on retained raw; 5-year retention without raw lifecycle rules can reach multiple exabytes.
  • Segment QPS: 10M concurrent viewers / 6 seconds = 1.67M segment requests/sec before manifests and retries.
  • Egress: 10M viewers x 3 Mbps = 30 Tbps sustained.
  • Transcode compute: 500 upload hours/minute x 3x real-time = 1,500 compute-hours/minute, about 90K core-equivalents.
  • Premiere origin budget: 1M viewers on one asset = 167K segment QPS for that title; at 99.9% CDN hit rate, origin sees ~167 segment req/s (<0.01% of total 1.67M segment QPS). Plan origin budget <1% of segment traffic.
  • Origin budget: if CDN hit rate is 99%, 1.67M segment QPS still leaves 16.7K origin QPS.

Design decisions forced by numbers

  • Never block playback on analytics or recommendation writes.
  • Use priority queues for transcode work and publish only validated manifests.
  • Warm popular media at the edge and apply origin shielding to protect object storage.

Scaling to millions

  • At 1M users: upload sessions, object storage, transcode queue, and CDN delivery are enough.
  • At 10M users: add priority transcode queues, origin shielding, and watch-event streams.
  • At 100M+ users: add regional placement, hot premiere cache warming, and adaptive degradation.

Readable flow

Upload session
Raw object
Transcode queue
Variants and manifest
CDN edge
Player

Interview follow-ups to expect

  • What happens if transcode fails after upload succeeds?
  • What CDN hit rate is needed to keep origin egress affordable?
  • Live streaming differs from VOD: live uses low-latency ingest and shorter segment windows; VOD uses pre-transcoded ladders and higher CDN hit rates.

Operational readiness checklist

After the math, explain how this capacity plan is measured, protected, launched, and evolved.

Observability

  • Attach each capacity estimate to a dashboard metric: p99 latency, queue age, cache hit rate, shard skew, error rate, and freshness lag.
  • Alert on rate-of-change and saturation, not only hard failures; backlogs and hot keys usually warn before an outage.

Security and abuse

  • Budget for auth checks, rate limits, quota isolation, audit logging, privacy filters, and abuse-review side paths.
  • Separate trusted internal events from user-controlled input so retries and backfills cannot bypass policy checks.

Degraded modes

  • Define the fallback when a dependency is slow: stale cache, partial results, read-only mode, delayed async work, or admission control.
  • Protect the invariant first; reduce freshness, personalization, or analytics quality before risking duplicate or corrupt state.

Testing and rollout

  • Test average, peak, and hot-object traffic; include retry storms, cold caches, lagging workers, and regional dependency loss.
  • Use canaries, shadow reads, dual-write validation, feature flags, and explicit rollback criteria for risky path changes.

Rollout, backfill, and runbooks

  • Make migrations and backfills idempotent, resumable, rate-limited, and visible through progress and error metrics.
  • Write the runbook before launch: owner, dashboards, paging thresholds, mitigation switches, replay steps, and repair commands.

10x evolution

  • For video streaming capacity math, state which number forces the next move: cache memory, shard count, write amplification, queue lag, egress, or failover reserve.
  • Add the next layer only when the metric forces it: sharding, regional reads, async replay, hot-key isolation, or stricter backpressure.

Playback operations and 10x plan

Protect origin and user experience when traffic spikes.

SLOs and metrics

Startup p99 <2s, rebuffer ratio <1%, manifest p99 <100ms, CDN hit rate >99%. Watch origin egress, shield hit rate, segment 4xx/5xx, transcode queue age, and watch beacon lag.

Degraded modes

If recommendations or watch analytics fail, playback continues. If origin is stressed, serve lower bitrates, lengthen cache TTL for immutable segments, and shed non-critical previews.

Testing and rollout

Load test segment QPS by cache-hit scenarios, chaos test origin shield loss, validate manifests before publish, canary new encoding ladders, and replay watch events into shadow feature tables.

10x evolution

Add regional origin shields, hot premiere cache warming, per-region egress budgets, multi-CDN routing, lifecycle deletion of raw assets, and separate live-stream ingest from VOD processing.

Hard-part drill: CDN miss storm

A new release gets 1M viewers before edges are warm. Route misses through origin shield, collapse concurrent segment fetches, pre-warm the first few minutes of segments, cap origin QPS per region, and temporarily bias ABR toward renditions already hot at the edge.

APIs worth naming

Upload session separate from stream manifest endpoint.

Keep upload APIs separate from the stream API. Return processing status until transcode completes; only expose the stream endpoint when status is ready.

POST/api/v1/videos/uploadStart resumable upload session
POST/api/v1/videos/upload/{id}/completeFinalize raw object; enqueue transcode
GET/api/v1/videos/{video_id}Metadata + processing status
GET/api/v1/videos/{video_id}/streamSigned manifest URL (after ready)
GET/api/v1/videos/searchOpenSearch-backed discovery
POST/api/v1/videos/{id}/likeSocial; async counters OK

Event bus

Kafka between ingest, transcode, catalog, and analytics.

How events connect the pipeline

A durable bus decouples upload completion from transcode, catalog updates, and analytics.

Publishers

Services write durable events after a safe step.

Fire after durable steps: raw upload closed, or transcode validated.

upload-completed

Ingest API

Raw object closed; metadata saved.

A workflow owner consumes the event and records the processing stages. Keying this topic by video_id preserves partition order for those records, but does not order separate completion topics or stop parallel workers from finishing out of order. Stage versions and expected-state checks supply that control.

transcode-completed

Packaging worker

All variants + manifest validated.

The catalog updater conditionally marks the validated output version ready. Prefer immutable versioned segment URLs so old and new encodes cannot share stale cache entries; then update search and other projections asynchronously.

watch-events

Player beacon

Play, pause, quartile, complete.

Analytics and recommendations only, never on the playback critical path.

Consumers

Separate worker pools drain topics at their own pace.

One pool for orchestration, one for catalog/search, one for analytics.

upload-completed

Transcode orchestrator

Enqueue resolution jobs per codec.

The orchestrator records child jobs, priorities, and their completion state before dispatch. Reserve bounded capacity for time-sensitive premieres while preventing ordinary uploads from starving. A duplicate upload event must find the existing workflow rather than launch another full encode.

transcode-completed

Catalog updater

Publish manifest pointers in DB.

Publish a new manifest pointer only after the referenced immutable output is validated and durable. Search indexing, the creator notification, and optional CDN pre-warming follow that committed transition. Those consumers can retry independently without announcing a video version that was never made ready.

watch-events

Analytics / ML

Aggregate watch time, train rankers.

Batch to the warehouse; real-time features can lag by minutes.

Simple rule of thumb

Keep watch-event processing and optional recommendation writes off the segment-delivery path. Confirm separately how entitlement, subscription, and advertising dependencies behave on failure: bypass, pause, cached authorization, or a clear error must follow the product contract and its freshness limit.

Data model (core tables)

videos

id PK
channel_id, title
status uploading|processing|ready|failed
manifest_urls JSON
duration_sec, view_count

Catalog row; bytes live in S3.

upload_sessions

upload_id PK
video_id, parts[]
expires_at

Track multipart state.

channels / users

channel_id, user_id
subscriber_count

Relational profile data.

watch_events

user_id, video_id, ts
watch_sec, completed

Append-only analytics stream.

CDN, bottlenecks, and failure modes

Transcode backlog

Risk: Uploads complete but stay "processing" for hours.

Mitigation: Priority queues, GPU pools, scale workers on queue age.

CDN miss storm

Risk: Viral video misses edge cache; origin egress spikes.

Mitigation: Origin shield, proactive cache warming, signed segment URLs.

Broken manifest

Risk: Player 404s mid-playback.

Mitigation: Publish manifest only after QC; atomic catalog update.

Storage cost

Risk: Raw + 6 renditions × petabytes.

Mitigation: Lifecycle to cold tier; drop raw after transcode; AV1 for long-tail.

Beginner vs advanced answers

Beginner (5 min)

Separate the control path from the media path. A metadata service owns videos, access, and processing status; object storage owns original and encoded bytes; workers create playback variants; the CDN serves segments. Adaptive bitrate lets the player choose a variant from measured throughput and buffer level. The essential correctness rule is that a published manifest refers only to available, compatible outputs.

Advanced (deep dive)

Inspect the lifecycle of one video from partial upload through validation, transcoding, publication, and deletion. Explain how a failed worker retries without publishing half a rendition, how origin shielding contains simultaneous cache misses, and how signed access survives normal playback but expires when intended. Live streaming adds a moving manifest and tighter segment-production deadlines, so it needs a separate freshness and recovery budget from video on demand.

Choosing and explaining Video streaming

A complete explanation connects the mechanism to a requirement. Describe what improves when you introduce it, which new failure cases become possible, and how you would know that the trade-off is worthwhile.

Explain the core idea

Two paths: async upload/transcode vs CDN-heavy playback.

Player reads manifest from API; segments from CDN (HLS/DASH ABR).

Never block playback on analytics or recommendations.

When it belongs

Design YouTube, Netflix, or Twitch-style VOD.

They ask about transcoding cost, CDN, or startup latency.

They probe live streaming vs uploaded video (call live a follow-up).

How it fails

Publishing manifest before all segments exist.

Streaming video bytes through API servers instead of CDN.

Synchronous transcode in upload HTTP handler.

Trade-offs to weigh

More renditions vs storage/transcode cost.

HLS vs DASH vs CMAF packaging.

Raw retention vs storage cost.

Common misunderstandings

Updating view_count on every segment fetch.

No origin shield at YouTube scale.

Ignoring rebuffer ratio as the playback SLO.

Deeper walkthrough

Video streaming deeper walkthrough

Upload is async and compute-heavy; playback is CDN-heavy and sensitive to startup time and rebuffering.

Requirement refinements

Clarify VOD vs live, DRM, offline download, recommendations, comments, regional rights.

Playback SLOs: startup latency, rebuffer ratio, supported devices.

API design details

Direct-to-S3 multipart upload with upload session id.

Stream API returns signed manifest + entitlements, not video bytes.

Data model and storage

Separate raw asset, variants, manifests, thumbnails, captions, processing status.

Watch events in analytics stream, not synchronous video row updates.

Scaling strategy

Transcode capacity follows incoming video minutes multiplied by rendition count and encoding cost. Scale from oldest queued work and completion targets, reserve capacity for urgent uploads, and cap per-job parallelism. More playback viewers primarily increase CDN delivery demand, not the number of times the same video should be transcoded.

An origin shield coalesces misses from many edge locations before they reach object storage. For a premiere, warm the required manifest and early segments while estimating egress at both high and low cache-hit rates. A globally cold object can overload origin even when the average catalog cache-hit ratio looks excellent.

Reliability, recovery, and operations

Write each rendition to an immutable temporary version and validate duration, codec metadata, and segment existence. Publish its manifest only after the required artifacts are durable. A worker crash can then retry or resume the same job without exposing a partially written version to viewers.

Monitor startup time, rebuffer, CDN hit rate, transcode queue age, origin egress.

Deepening reference

Video Streaming: realistic production notes

Beginner mental model: Video platforms are two systems: an upload/transcode pipeline and a CDN-heavy playback path.

Production scope: The upload side is write-heavy and asynchronous. The playback side is read-heavy, latency-sensitive, and depends on CDN hit rate, adaptive bitrate manifests, and regional origin shielding.

Choose what the first version must guarantee

Start by deciding which video streaming capabilities are essential. Describe the main read and write operations before choosing infrastructure. For each operation, identify the stored records it uses and the condition that makes its result correct. A fast response is useful only if it satisfies that condition.

Next, separate work the user must wait for from work that can finish later. Estimate requests per second, storage growth, and the busiest object or customer. Use those estimates to choose one bottleneck to investigate. The calculations below are example workloads with stated assumptions; they are not measured limits of a particular product.

Concrete capacity calculations

Upload: 500 hours/minute = 720K hours/day. At 10 Mbps raw bitrate, ingest is about 3.24 PB/day.

Segment QPS: 10M concurrent viewers / 6 seconds = 1.67M segment requests/sec before manifests and retries.

Egress: 10M viewers x 3 Mbps average = 30 Tbps sustained.

Transcode compute: 500 upload hours/minute x 3x real-time = 1,500 compute-hours/minute, about 90K core-equivalents.

Origin budget: at 99% CDN hit rate, 1.67M segment QPS still leaves about 16.7K origin QPS.

Variant storage: encoded ladder can be 2x to 4x mezzanine size; raw lifecycle rules matter for multi-year retention.

Scaling to millions of users

Keep upload completion separate from processing completion. Users should see processing states while transcode workers scale by queue age.

Partition object storage by media_id and region; keep metadata in a strongly indexed store by owner_id, media_id, and status.

Serve playback through edge caches with origin shielding, request collapsing, and pre-warming for known high-demand releases.

Use adaptive bitrate manifests so clients switch renditions based on bandwidth rather than buffering.

Treat rights, privacy, and takedown decisions as fast metadata checks before issuing playback references.

Sequence and data-flow diagram

Walk this path after the high-level design so it is clear what is synchronous, what is asynchronous, and where the system can degrade safely.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
  participant C as Creator
  participant U as Upload API
  participant O as Object storage
  participant Q as Job queue
  participant T as Transcode workers
  participant E as Edge cache
  participant V as Viewer
  C->>U: Start upload
  U->>O: Store raw media
  U->>Q: Enqueue processing job
  Q->>T: Process renditions
  T->>O: Store segments and manifest
  V->>E: Request manifest and segments
  E->>O: Fetch on cache miss
  E-->>V: Stream segments

Core flow to walk through

1

Upload: direct-to-object-storage upload, create metadata, publish transcode job.

2

Transcode: generate multiple resolutions, bitrates, thumbnails, captions, and manifests.

3

Playback: client fetches manifest, chooses segments by bandwidth, CDN serves chunks near the user.

Production readiness

Video Streaming: ship, operate, and evolve

Now examine the same request flow during failures and deployments. Tie each operational control to the user behavior it protects.

Observability

Track video streaming p95/p99 latency, error rate, saturation, and user-visible freshness separately for read, write, and async paths.

Alert on leading indicators such as queue age, hot-key skew, cache miss storms, reconciliation mismatches, and error-budget burn.

Security and abuse

Enforce authentication, authorization, rate limits, input validation, audit trails, and privacy checks at the service boundary.

Treat abuse controls as a first-class path: throttling, quota isolation, moderation hooks, revocation, and safe handling of sensitive data.

Degraded modes

Name what still works if cache, search, ranking, stream processing, object storage, or a regional dependency is slow.

Prefer stale-but-safe reads, partial results, async retry, admission control, and feature disablement over corrupting core state.

Testing and rollout

Load test average, peak, and hot-object traffic; add failure-injection for retries, timeouts, backlog growth, and dependency outages.

Ship with canaries, shadow reads or dual writes when useful, rollback switches, schema compatibility checks, and replay validation.

Runbooks

Document dashboards, paging thresholds, owner actions, rollback steps, data repair commands, and customer-impact language.

Keep backfills and replays idempotent, resumable, rate-limited, and observable so repair work does not create a second incident.

10x evolution

Say which metric forces the next architecture change: shard count, cache footprint, write amplification, queue lag, p99 latency, or regional failover reserve.

Evolve one bottleneck at a time: partition by access pattern, isolate hot tenants, regionalize reads, add replayable async pipelines, then harden multi-region behavior.

Hard parts worth deepening

Never block upload completion on full transcode completion; show processing state.

Use adaptive bitrate so playback can survive network changes.

Separate hot popular content from cold long-tail storage.

Protect origin from cache miss storms with shielding and pre-warming for premieres.

Failure modes and recovery

Transcode backlog grows; scale workers by queue depth and prioritize fresh uploads.

CDN miss storm overloads origin; use origin shield, request collapsing, and regional cache warming.

Bad transcode creates corrupt segments; validate manifests and segment checksums before publishing.

Rights rule changes; enforce geo and entitlement checks before signed playback URLs.

Signals to monitor

Playback startup time measures the wait before the first playable frame. Rebuffer ratio measures the fraction of the chosen playback interval spent stalled; define that denominator consistently so comparisons are meaningful.

Compare CDN hit rate with origin egress, the bytes leaving origin storage. Falling cache efficiency can increase both cost and origin load. Transcode queue age identifies creators whose uploads are waiting even while existing videos play normally.

ChoiceBest whenCost
Pre-transcode all qualitiesFast playback startup matters.High compute and storage.
Just-in-time transcodeLong-tail content is rarely watched.First viewer pays latency.
CDN signed URLsPremium/private content needs protection.More auth complexity and cache-key care.

Try this scenario

Describe what happens when a live premiere starts and 5 million users request the same manifest in 30 seconds.

Takeaway

Remember the YouTube tap: the hard work already happened when the creator uploaded. Playback should be a thin path: auth, a signed manifest, then CDN segments with ABR. Keep upload → Kafka → transcode → QC publish separate from that path, protect origin with a shield, and never let analytics block the first frame.

Primary sources

Practice and further reading

Use these exercises to connect the lesson to a design decision. State your assumptions, trace what happens to one request, and explain the rule that must remain true even during a failure. That rule is the design's correctness invariant.

Focus for this lesson: Separate upload/transcode/origin from CDN playback, ABR manifests, DRM, live latency, QoE, origin shielding, and capacity economics.

Explain the decision

How does adaptive bitrate streaming react to bandwidth changes?

Read the reasoning

The player estimates throughput/buffer health and switches among aligned encoded segments; manifests describe available variants.

Apply it to a production scenario

A popular live event causes cache misses at segment boundaries. What protects origin?

Read one approach

Pre-position, shield/coalesce fills, use immutable segment URLs, scale packagers/origin, and stagger manifest refresh where safe.

Work through the numbers

One million viewers average 4 Mb/s. Estimate aggregate delivery egress.

Read the worked calculation

About 4 Tb/s, overwhelmingly a CDN problem; origin traffic depends on edge hit and shielding.

Reason through a failure

What must transcoding publication preserve?

Read the recovery reasoning

A manifest references only complete, checksummed, playable segments/variants; partial outputs never become discoverable.