Notes
Listen
Requirements. A member browses a personalised home page of rows, picks a title and presses play on any device, choosing audio language and subtitles. They can stop on the TV and resume on their phone at the same second. Content must be protected with DRM, because studios require it. Billing, sign-up and live events are out of scope, and there are no user uploads at all, which is a big simplification.
Qualities. Playback should start in a second or two and almost never stall, at the best quality the connection allows. The design point is peak hour: evenings, and especially the night a big series launches. Browsing and playback should survive losing an entire cloud region. The resume point can be eventually consistent; being off by a few seconds is fine.
- in scope:
- • browse a personalised home
- page of rows
- • play a title on TV, phone,
- laptop; pick audio + subs
- • resume where you left off,
- on any device
- • protect content (DRM)
- out: billing, sign-up, user
- uploads, games, live events
- play starts in ~1-2 s
- rebuffering very rare
- best quality the link allows
- peak hour is the design point:
- evenings, weekends, launches
- browsing and playing must
- survive a failed cloud region
- resume point: eventual, fine
Ask scale
Assume three hundred million members, a hundred million watching on a given day for two hours each. That's two hundred million hours a day. Spread evenly, about eight million streams at once, but viewing bunches up in the evening, so plan for about three times that: twenty-five million concurrent streams. At five megabits each, that's over a hundred terabits a second at peak. That number decides the whole architecture.
Now the surprising number. Ten thousand titles averaging ten hours, counting every episode, is around a hundred thousand hours of content. Even with every resolution, codec, audio track and subtitle, that's only a few petabytes in total. The popular slice for one region is a few hundred terabytes, which fits on a rack of cache servers. So you can put the content right next to viewers before they ask for it.
members 300M
daily viewers 100M
hours/viewer/day 2
= 200M hours/day
avg concurrent = 200M / 24
= ~8M
peak (x3) = ~25M
avg bitrate 5 Mbps
peak egress = 25M x 5 Mbps
= ~125 Tbps titles ~10K avg hours per title ~10 = ~100K hours of content all renditions, codecs, audio, subs ~30 GB/hour = ~3 PB total catalog popular slice per region = a few hundred TB -> fits on a cache cluster inside one ISP
Define API
The API. The home call returns rows of titles with artwork for this profile. The key call is playback start: the device describes its capabilities, like supported codecs, HDR and screen size, and gets back a manifest tailored to it, a ranked list of cache URLs, and the available audio and subtitle tracks. A licence call exchanges a DRM challenge for decryption keys. And the player sends a heartbeat with the position every so often.
GET /v1/home?profile=..
-> rows[{ title, artwork }]
POST /v1/playback/start
{ titleId, device, caps }
-> { manifest, cacheUrls[],
audio[], subs[] }
POST /v1/license
{ challenge } -> { keys }
POST /v1/heartbeat
{ titleId, positionSec } Data model
Data model. Titles and their encoded assets are small and change rarely, so they're cached everywhere. Viewing history is the big, write-heavy one: a row per profile and title with the last position. It fits a wide-column store like Cassandra, replicated across regions, which Netflix has publicly described using for this. A cache map records which files each cache server holds and whether it's healthy. And precomputed home rows are stored per profile.
title (titleId, type, meta)
asset (titleId, codec, res,
bitrate, fileKey)
history PK (profileId),
cluster (titleId)
-> positionSec, updatedAt
wide-column, multi-region
cachemap (cacheId, region,
fileKeys[], health)
rows profileId -> ranked rows High-level design
Draw the control plane first. It runs in the cloud and handles everything except video bytes: sign-in, the home page, search, deciding what to play, licences and history. When you press play, the playback service picks the right files for your device, asks steering which caches should serve you, and arranges a DRM licence. These are small, latency-sensitive API calls, and Netflix has publicly described running this part on AWS across several regions.
Now the data plane. Encoded files sit in origin storage, but viewers almost never touch it. Each night, a fill planner predicts what each region will watch tomorrow and copies those files to cache servers placed inside internet providers and at internet exchange points. Then when you press play, your TV streams from a cache that might be in your own city. Netflix calls its version of this Open Connect, and it's publicly documented.
Deep dive: caches
Deep dive one: placement. Because the catalog is known, you don't wait for a cache miss. A planner forecasts demand per region from popularity and the release calendar, and pushes files during the quiet early-morning hours when the links are idle. Caches inside providers hold the hottest titles; caches at exchange points hold a wider set. Caches can fill from nearby peers instead of origin. For a big launch, the files are on the edge days before release.
Why is this better than a normal pull-through CDN? A pull CDN fetches on the first miss, which at nine pm on launch night means a storm of misses. Pre-positioning means the file is already there. Providers like it because the traffic stays inside their network. And encoding is tuned per title: an animated show compresses far better than a grainy action film, so each gets its own bitrate ladder, which Netflix has written about publicly.
- predict demand per region:
- popularity, new releases
- fill during off-peak hours
- (early morning local time)
- tiers: ISP cache holds the
- hottest, exchange cache
- holds a wider slice
- caches fill from peers before
- going back to origin
- launch day: fill days ahead
- no cold misses at peak: the
- file is already there
- ISP saves transit; serving
- stays inside its network
- fill uses idle night capacity
- per-title encoding: ladder
- tuned to each title, so a
- cartoon needs fewer bits
- than an action film
Deep dive: play start
Deep dive two: starting playback. The playback service takes your device's capabilities and picks matching files. Steering looks at your network location and the cache map, and returns a ranked list of caches that actually hold those files, are close and aren't overloaded. The licence request runs in parallel. The player fetches a few low-bitrate segments, starts, then climbs to higher quality. If a cache fails mid-stream, the player moves to the next one on the list.
A word on DRM. Files are encrypted once, during encoding, so caches only ever store ciphertext; a stolen cache disk is useless. The player sends a licence challenge, and the licence service checks the membership, the device and the region before returning keys bound to that device. The licence call is on the critical path of every play, so it has to be fast and highly available, just like steering.
- 1 playback/start: device caps
- 2 steering: caches that hold
- these files, near the user,
- healthy, not overloaded
- 3 licence request in parallel
- 4 player fetches low-bitrate
- first segments, starts
- 5 climbs the ladder (ABR)
- cache fails -> next in list
- files encrypted once at
- encode time
- caches store ciphertext only
- device sends licence challenge
- licence server checks member,
- device, region, then returns
- keys bound to the device
- licence service is on the
- critical path: keep it fast
Deep dive: history
Deep dive three: viewing history. Twenty-five million streams sending a heartbeat every thirty seconds is over eight hundred thousand writes a second at peak. Each heartbeat upserts one row for the profile and title, and the newest timestamp wins. A wide-column store that accepts writes locally in each region and replicates asynchronously handles that easily. If you switch devices, the new one reads the latest position, which may be a few seconds behind. That's fine.
25M streams, 1 beat / 30 s = ~830K writes/s at peak write: upsert (profile, title) last-write-wins by timestamp read: on home page + play store: wide-column, local writes in each region, async replication also feeds the event stream
Trade-offs
Failures. If a whole cloud region fails, members are shifted to the other regions, which are sized to absorb the extra load. If a dependency like personalisation is slow, serve a fallback, such as a generic popular row, instead of an error. If a cache dies, steering stops sending people there and active players switch. Netflix popularised deliberately injecting failures in production to prove this works. The headline metric is successful play starts per second.
Trade-offs. Pre-positioning copies the same files onto thousands of caches, spending storage to eliminate misses, and it only works because the catalog is small and known. Per-title encoding spends compute up front to save bandwidth on every view. Eventually consistent history accepts a few seconds of drift so each region writes locally. At ten times the scale: more caches inside providers and more efficient codecs like AV1.
- cloud region down: shift
- members to other regions,
- each sized for extra load
- dependency slow: fallbacks,
- e.g. a generic home row
- cache down: steering skips it,
- player switches mid-stream
- practice: inject failures on
- purpose (chaos testing)
- watch: play starts/s, rebuffer
- pre-positioning: storage on
- many caches for zero misses
- (works because catalog is
- small and known)
- per-title encoding: compute
- for fewer bits
- eventual history: seconds of
- drift for regional writes
- 10x: more ISP caches, AV1
Say it like this
The summary. Peak is about twenty-five million streams and over a hundred terabits a second. A multi-region cloud control plane handles browsing, playback decisions, licences and history. The catalog is encoded ahead of time with per-title ladders and encrypted. Each night, files are pre-positioned in caches inside providers and at exchanges. Steering gives each play a ranked list of healthy caches that hold the file. History is heartbeat upserts in a regional wide-column store.
- peak ~25M streams, ~125 Tbps
- control plane in the cloud,
- multi-region active-active
- catalog encoded ahead,
- per-title ladders, encrypted
- nightly fill to ISP and
- exchange caches
- steering: ranked healthy
- caches with the file
- history: heartbeats, LWW