Netflix System Design
Cheat Sheet
Cheat Sheet
Review, then close β the interview tests recall, not reading.
Opening Scripts
I'd design Netflix's playback backend as a 10-service orchestration chain. A user clicks Play β Gateway validates JWT β Subscription Service confirms active plan β Concurrency Service checks stream limits atomically in Redis β Playback Service calls DRM and Manifest Service β client gets manifest URL and fetches video bytes directly from the nearest Open Connect CDN appliance. During playback, clients send a heartbeat every 30 seconds. That's 60M concurrent streams Γ· 30s = 2M writes/sec β which rules out MySQL and drives the choice of Cassandra for watch_progress. I'll deep dive on concurrency enforcement, watch progress storage, and CDN handoff.
Netflix serves 300M subscribers. I'll assume 220M DAU, 60M peak concurrent streams, 5 Mbps average bitrate. Functional requirements: start playback, enforce concurrent stream limits, track watch progress for resume, deliver video globally. Non-functional: availability over consistency for playback (every second of downtime is revenue), sub-2-second playback start, eventual consistency for watch progress (30-second staleness is fine), strong consistency for concurrency and billing. Scale: 60M streams Γ 5 Mbps = 300 Tbps CDN bandwidth. 60M Γ· 30s = 2M heartbeat writes/sec. That immediately rules out MySQL. Architecture: 10-service chain. Gateway β Auth β Subscription β Concurrency (Redis Lua) β Playback β DRM (fail-closed, legal) β Manifest β CDN. Watch Progress is an async write path β it doesn't block session start. Key DB decisions: Cassandra for watch_progress (2M writes/sec, partition by profile_id), Redis for concurrency state (atomic Lua script, 60 GB for 60M sessions), MySQL for billing (ACID), EVCache for metadata (99.9% hit rate at 30M req/s). Key tradeoff: DRM is the only fail-closed service β legal requirement. Everything else fails open. Watch progress uses eventual consistency by design.
Main Services (10)
API List (5 core)
/v1/playback/sessionsIdempotent on client session_id/v1/playback/heartbeatIdempotent on session_id + event_ts/v1/playback/sessions/{id}Removes from Redis, marks Cassandra row/v1/watch-progress/{profile_id}Returns all in-progress content/v1/metadata/{content_id}Returns from EVCache, fallback CassandraDatabase Choices
2M writes/sec, partition by profile_id, ONE consistency
Atomic Lua script for concurrency check, 60 GB fits in memory
ACID required β double-charge is catastrophic
30M req/s at 99.9% hit rate, in-process cache
Cache Strategy
Playback Flow (15 steps)
POST /playback/sessions (client sends session_id UUID)
Gateway: validate JWT
Auth Service: verify identity
Subscription Service: check plan β fail open
Concurrency Service: Redis Lua atomic check-and-add β fail closed
Playback Service: orchestrate downstream
DRM Service: issue device-bound license β fail closed (legal)
Manifest Service: return ABR manifest with CDN URLs
Response: manifest_url + drm_license_url + heartbeat_interval_sec
Client: parse manifest
Client: fetch first segment from nearest OCA appliance
CDN: serve video bytes (no API involvement)
Client: start heartbeat loop every 30s
Heartbeat: POST /heartbeat β Watch Progress β Cassandra ONE write
Session end: DELETE session β Redis SREM + Cassandra update
Top 5 Failures
DRM Service down
Fail closed β no playback. Legal requirement.
Redis (concurrency) down
Fail open with fallback count check in Cassandra
EVCache cold start
Thundering herd β mutex lock on miss, one filler thread
Cassandra heartbeat write fails
Client retries with exponential backoff; eventual consistency means 30s staleness is ok
CDN node fails
Client retries to parent cluster β origin S3. API layer is unaffected.
Top 4 Tradeoffs
Strong: concurrency (Redis), billing (MySQL). Eventual: watch progress (Cassandra ONE).
Redis for concurrency (atomic ops). Cassandra for write-heavy time-series data.
DRM: fail closed (legal). Subscription: fail open (availability > revenue loss).
Watch progress is async β doesn't block session start. Billing is sync.
Scale Numbers (memorize the derivation, not the number)
300M subscribers Γ 0.73= 220M DAU220M Γ 0.27 peak= 60M concurrent streams60M Γ 5 Mbps= 300 Tbps CDN60M Γ· 30s heartbeat= 2M writes/sec β Cassandra30M metadata reads/sec Γ 99.9%β 30K reach Cassandra60M Γ 1KB Redis SET entry= 60 GB Redis for concurrency2M writes/sec Γ· 200/node= ~10,000 Cassandra nodes