Netflix
Global video streaming — CDN economics, ABR, DRM, chaos engineering, Open Connect.
The scenario
Video streaming at 300M subscribers — where the CDN IS the architecture
Same startup, same engineer #4. Fifth Monday.
Your CTO drops by. "Users love shortener, chat, Instagram-style feed, and Twitter timelines. Now we want to add video-on-demand. Movies, TV series, some short-form. Adaptive bitrate. Global. 4K. Downloads for offline. Ship an MVP in 12 weeks."
She pauses. "By the way — one of our licensed titles just went viral. 5 million people started streaming it in the same hour last night. Our S3 bill was $180,000 for that one night alone."
Welcome to video streaming.
Here's the paradigm shift:
URL Shortener, Slack, Instagram, Twitter — all shared one thing: the payload was small. A short_code is 7 bytes. A tweet is ~280. A photo is ~200 KB. Even Slack messages are ~1 KB.
A movie is 5 GB. A 4K show binge is 50 GB per user per weekend. (Netflix's average bitrate is 5 Mbps at HD, 15 Mbps at 4K.) You don't design video the way you design tweets. The CDN isn't a component — the CDN IS the architecture.
That $180K S3 bill teaches the whole lesson: egress bandwidth is the entire cost. Netflix's answer, brilliantly, was to build their own CDN — the Open Connect Appliance (OCA) — and give it away for free to ISPs. It's the second-most-important architecture decision they've ever made (after "streaming, not DVD"), and if you don't mention it in the interview, you'll fail.
The real 2024 numbers
Before we design anything, know the scale you're designing against:
- ~300M paid subscribers (Netflix Q4 2024 earnings)
- ~65M peak concurrent streams (Netflix Squid Game S2 launch, Dec 2024)
- ~17,000+ Open Connect Appliances embedded in ISPs globally (Open Connect deployment map)
- ~200 Tbps peak egress across all OCAs at prime time
- ~15 billion events/day through Keystone (Netflix's Kafka pipeline) (Netflix Tech Blog: Keystone)
- ~99.99% availability during regional AWS incidents (via Chaos Monkey engineering — Netflix invented it in 2011)
Interview soundbite: "Netflix at 300M subscribers is not a video-storage company. It's a global CDN with a video catalog on top. 95%+ of bytes leaves customer devices from an OCA embedded 1-2 hops from the customer, not from AWS."
The whole journey at a glance
Every 10× in subscriber scale shifts what's expensive:
text═══════════ NETFLIX ARCHITECTURE ACROSS 4 SCALES ═══════════ L4 (100K subs) L5 (50M subs) L6 (200M subs) L7 (300M subs, global) S3 + CloudFront Multi-region + DRM Open Connect CDN 17K+ OCAs · Keystone 12 weeks · $50K/mo 12 months · $2M/mo 24 months · $50M/mo ongoing · $2B/yr ┌────────┐ ┌────────┐ ┌── Global CloudFront ┐ ┌── Own Open Connect ──┐ │ Web │ │ Web │ │ + DRM licenses │ │ 17,000+ OCAs at ISPs│ │TV apps │ │TV apps │ │ regional cache │ │ 95%+ traffic served │ └───┬────┘ └───┬────┘ └─┬──┬──┬──┬─────────┘ │ from 1-2 hops away │ │ │ │ │ │ │ └──┬──┬──┬──┬─────────┘ ┌──▼───┐ ┌──▼──┐ ┌──▼──▼──▼──▼─────┐ │ │ │ │ │ ALB │ │ ALB │ │ Multi-region │ ┌────▼──▼──▼──▼──────────┐ │ │ │ │ │ ALB · Zuul │ │ Zuul API Gateway │ └──┬───┘ └──┬──┘ │ API gateway │ │ (custom Java by NF) │ │ │ └───┬──────┬──────┘ │ 200K+ RPS routing │ │ │ │ │ └──┬──────┬──────┬───────┘ ┌──▼──────┐ ┌───▼─────────┐ ┌───▼──────▼──────┐ │ │ │ │ Monolith│ │ Microserv. │ │ 1000+ Micros │ ┌──▼──────▼──────▼──────┐ │ Java │ │ 100+ svcs │ │ Java Spring │ │ Recommendation engine │ │ 1 API │ │ Spring Boot │ │ Boot / Cassandra│ │ (Cinematch → LTV pred)│ │ + MySQL │ │ + Cassandra │ │ │ │ + Personalization ML │ └──┬──────┘ │ + EVCache │ └───┬─────────────┘ └──┬──┬──┬──┬───────────┘ │ └───┬─────────┘ │ │ │ │ │ │ ┌───▼──┐ │ ┌──▼──▼──▼──▼──────────┐ │ │EVCache│ │ │ Cassandra + EVCache │ │ │Netflix│ │ │ + S3 for cold blobs │ │ │memcached ┌─▼────────────┐ │ + Iceberg data lake │ │ │variant│ │ Regional S3 │ └──┬───────────────────┘ │ └───┬──┘ │ + Push to OCA│ │ │ │ └───┬──────────┘ ┌──▼──────────────────┐ ┌──▼───┐ ┌───▼─┐ │ │ Keystone (Kafka + │ │MySQL │ │Cassandra │ │ Flink + Iceberg) │ │(user+│ │+ EVCache│ │ │ 15B events/day │ │title+│ │+ S3 │ │ │ real-time analytics │ │DRM) │ │multi-AZ │ │ └─────────────────────┘ └──────┘ └─────────┘ │ ▼ Open Connect Appliances (OCAs) Push videos here at 03:00 local time Play from 1-2 hops from user ↑ ↑ ↑ ↑ Boring CloudFront + DRM Own the CDN. Open 17K OCAs. Keystone. MVP: S3 + Multi-region. Connect Appliances. Chaos Monkey. Zuul. CloudFront. 100+ Java Spring Push content to 15,000+ 95% traffic from Add-on: DRM. Boot services. ISPs at 3am. 1-2 hops away. Chapter 5 Chapters 6+6.5 Chapter 7+7.5 Chapter 8 walks walks through walks through walks through the through multi-region CDN, the Open Connect Keystone pipeline, L4 MVP DRM, per-title economics + push personalization ML, encoding algorithm and cost as strategy Key insight: video is not about STORAGE. It's about EGRESS. At 300M subscribers, 95%+ of the bytes leaving your customer's device come from an appliance 1-2 hops from them, not from your cloud. That's Open Connect. That's the entire architecture.
The same 4 tiers as clean architecture diagrams
The ASCII compressed all four tiers. Here are the same shapes as clean Mermaid:
L4 · 100K subs · S3 + CloudFront · $50K/mo · 12 weeks:
flowchart TD
W([Web / TV / mobile apps]) -->|HLS/DASH| CF[CloudFront CDN<br/>$40K/mo egress]
W --> API[Netflix API<br/>1 Java monolith<br/>Spring Boot]
API --> MY[(MySQL Multi-AZ<br/>users + titles + entitlements)]
API --> S3[(S3<br/>video segments<br/>~$10K/mo storage)]
S3 -->|origin fetch on miss| CF
classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
class CF,API,MY,S3 nL5 · 50M subs · multi-region + DRM · $2M/mo · 12 months:
flowchart TD
W([Global apps]) -->|HLS/DASH| CF[CloudFront regional<br/>us-east · eu-west · ap]
W --> API[Regional API<br/>100+ microservices]
API --> DRM[DRM License Server<br/>Widevine · PlayReady · FairPlay]
API --> C[(Cassandra + EVCache<br/>metadata + watch state)]
API --> S3[(Regional S3<br/>+ ABR ladders per title)]
API --> REC[Recommendation svc<br/>Cinematch<br/>collaborative filtering]
REC --> C
S3 -->|origin fetch| CF
classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef m fill:#fef3c7,stroke:#d97706,color:#78350f
class CF,API n
class C,S3,DRM,REC mL6 · 200M subs · Open Connect CDN · $50M/mo · 24 months:
flowchart TD
W([Global users]) -->|HLS| OCA[Open Connect Appliances<br/>15K+ at ISPs<br/>95% traffic served]
W -->|control plane only| API[Regional API]
API --> DRM[DRM License Server]
API --> C[(Cassandra multi-region<br/>+ EVCache)]
API --> S3[(Regional S3<br/>master + ABR ladders)]
S3 -.->|nightly push at 03:00 local| OCA
API --> REC[Personalization ML<br/>+ real-time behavior]
REC --> C
classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef m fill:#fef3c7,stroke:#d97706,color:#78350f
classDef oc fill:#dcfce7,stroke:#16a34a,color:#14532d
class API n
class C,S3,DRM,REC m
class OCA ocL7 · 300M subs · 17K+ OCAs + Keystone · $2B/yr infra:
flowchart TD
W([Global users]) -->|HLS/DASH| OCA[17,000+ Open Connect Appliances<br/>at ISPs · 200 Tbps peak<br/>95%+ traffic 1-2 hops from user]
W -->|control plane| ZUUL[Zuul API Gateway<br/>Netflix-built Java<br/>200K+ RPS routing]
ZUUL --> API[1000+ microservices]
API --> DRM[Multi-DRM License Server]
API --> C[(Cassandra multi-region · 3x replica)]
API --> EVC[EVCache<br/>Netflix's memcached fork]
API --> S3[(Regional S3<br/>master + ABR)]
API --> KS[Keystone pipeline<br/>Kafka + Flink + Iceberg<br/>15B events/day]
KS --> ML[Personalization + LTV<br/>ranking models · retention pred]
ML --> API
S3 -.->|nightly push at 03:00| OCA
classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef m fill:#fef3c7,stroke:#d97706,color:#78350f
classDef oc fill:#dcfce7,stroke:#16a34a,color:#14532d
class ZUUL,API,EVC n
class C,S3,DRM,KS,ML m
class OCA ocWhy every 10× breaks the architecture
Look at the four tiers side-by-side. Three patterns dominate:
- Compute stays roughly the same. APIs, DBs, metadata services — they scale by adding more of the same. Boring.
- The CDN is the whole story. L4 = CloudFront. L5 = regional CloudFront. L6 = your own OCAs at ISPs. L7 = 17K OCAs pushing 200 Tbps. The "we serve videos" problem transforms into "we own the last mile of every ISP" problem.
- The data pipeline emerges. L4 has no analytics. L5 uses simple aggregates. L6 needs a real streaming pipeline (Kafka + Flink). L7 has Keystone doing 15B events/day for personalization + billing + observability.
The 3 senior insights before we start Chapter 1
- Open Connect is the moat, not the codec. Every candidate knows about H.264/H.265/AV1. Very few can explain how Netflix negotiated with 15,000+ ISPs to embed their CDN appliances for free. That relationship IS the architecture — anyone can add H.265; nobody can duplicate 17,000 appliances 1-2 hops from every customer. Reference: Open Connect ISP FAQ.
- Push-at-3am, don't pull-on-demand. Traditional CDNs pull content when a customer requests it (cache miss = origin fetch). Netflix INVERSED this. At 03:00 local time to each OCA, they PUSH the next day's expected-popular titles, based on ML predictions. Cache hit rate ≈ 95%+ because the popularity model works. Reference: Open Connect predictive push.
- Keystone is Kafka, not custom. Netflix's data pipeline (Keystone) is 90% off-the-shelf Kafka + Flink + Iceberg, custom-tuned. It handles 15 billion events/day. Do NOT say "Netflix uses a proprietary data pipeline" — that's a common tutorial mistake. Reference: Netflix Tech Blog: Keystone Real-Time Stream Processing.
Chapter map for the journey ahead
- Chapter 1 — Requirements (functional + non-functional per level)
- Chapter 2 — Capacity estimation (300M subs, 200 Tbps peak, 65M concurrent)
- Chapter 3 — API design (playback, catalog, user, billing)
- Chapter 4 — Data model (titles, users, entitlements, watch history)
- Chapter 4.5 — The video pipeline: master file → transcoding → ABR ladder → OCA push
- Chapter 5 — L4 MVP: S3 + CloudFront. Works up to 100K subscribers
- Chapter 6 — L5: multi-region + per-title encoding + DRM
- Chapter 6.5 — Per-title encoding: how Netflix saves 25% bandwidth per title
- Chapter 7 — L6: Open Connect Appliance CDN. Push at 3am.
- Chapter 7.5 — The Keystone data pipeline: Kafka + Flink + Iceberg
- Chapter 8 — L7: 17K OCAs + personalization ML + Chaos Monkey engineering
- Chapter 9 — Failure modes: OCA loss, DRM outage, viral title thundering herd
- Chapter 10 — Trade-off matrix
- Chapter 11 — Interview masterclass: 45-min mock, questions to ask
- Chapter 12 — Defense: the 20 hardest interview questions on Netflix
Ready? Chapter 1 next: what did the CTO actually ask for?
Netflix at 300M subscribers is not a video-storage company — it's a global CDN with a video catalog on top. 95%+ of egress leaves customer devices from 1 of 17,000 Open Connect Appliances embedded 1-2 hops from the customer at their ISP. The push-at-3am algorithm makes cache hit rate 95%+. Egress is the whole cost model.
- Why is Netflix fundamentally a CDN company, not a video-storage company?
- What is an Open Connect Appliance and why is it Netflix's architectural moat?
- What is push-at-3am and how does it achieve 95% cache hit rate?
- What does 300M subscribers imply for egress capacity (200 Tbps peak)?
- What is Keystone and what does it NOT do (custom Kafka replacement)?
Every concept below has its own interactive, animated page in the Learning Tracks section. Read them any time you want to go deeper than the mentor prose above — they're the reusable foundation this chapter is built on.
Open Connect uses a push-based model instead of cache-invalidation — understanding why is key to grasping the whole architecture.
Keystone is Netflix's Kafka-based data pipeline handling 15B events/day. Same tool, radically different scale.
Chapter 1 next: what did the CTO actually ask for? Playback, catalog, downloads, DRM, recommendations — each has functional and non-functional requirements. Get these wrong and you'll design the wrong system for the whole 12 chapters.
Components used in this design
Study each component's deep dive to understand it in isolation.
Load Balancer
Distributes incoming traffic across a pool of servers for scale and fault tolerance.
CDN (Content Delivery Network)
A globally distributed cache that serves static and cacheable dynamic content close to the user.
Redis
An in-memory key-value store used for caching, pub/sub, rate limiting, distributed locks, and simple queues.
NoSQL Database
Umbrella for document, wide-column, and key-value stores optimized for horizontal scale over strict schema.
Kafka
A distributed, partitioned, replicated commit log for event streaming, high-throughput ingest, and decoupled services.
Object Storage (S3, GCS, Azure Blob)
Durable, cheap, flat-namespace storage for blobs — images, videos, backups, logs, and any large binary object.
Stream Processor (Flink, Kafka Streams, Spark Structured Streaming)
Continuous computation over event streams — windowed aggregations, joins, ML features, and event-driven derived views.
Scheduler (cron, Airflow, Temporal timers)
Runs jobs at a time or interval — the simplest form of eventual asynchronous computation.
Workflow Engine (Temporal, Cadence, AWS Step Functions)
Orchestrates long-running, stateful multi-step processes — the right tool when a business flow involves many services and can span days.
Service Discovery (Consul, etcd, DNS-based)
How services find each other in a dynamic fleet — because IPs change, nodes come and go, and hardcoding is a losing game.
Distributed Database (DynamoDB, Cassandra, Spanner)
Horizontally-scaled database with automatic partitioning and replication — the answer when one node can't hold the data or the traffic.
Patterns applied in this design
Study each pattern's deep dive for the recurring solution logic.
Cache-aside (Lazy loading)
Reads dominate your workload, and every read hits a slow store (database, disk, network). Latency and load on the primary storage climb until the primary becomes the bottleneck.
Circuit breaker
A downstream service is unhealthy. Your service keeps calling it, waiting the full timeout on every call, exhausting your thread pool, and cascading the failure back to your callers.
Consistent hashing
You need to shard keys across N nodes, but N changes over time (nodes added, removed, or failed). Naive hash-mod-N reshuffles almost everything on every change — cache is wiped, migration cost is huge.
Bulkhead
One misbehaving caller or workload consumes all your resources (threads, connections, memory) and starves everyone else.
Explore next — related systems
If you enjoyed this problem, these share similar patterns or challenges.