Netflix Interview Questions | JiQuest

add

#

Netflix

System design deep dive · HLD

Design Netflix: full high-level design.

Requirements, back-of-envelope capacity estimation, a high-level design diagram, a deeper deployment architecture diagram, sequence diagrams for the transcoding pipeline and adaptive-bitrate playback, and an entity-relationship diagram for videos, encodings, watch history, and subscriptions - with the reasoning an interviewer expects behind every box and arrow.

260MSubscribers worldwide
~40MPeak concurrent streams
99%+Requests served from CDN edge
TV / appplays title Playback APIsigns manifest ABR ladder240p → 4K CDN edgesegment served Origin storeon cache miss segments stream to player

1. Clarify requirements before drawing any box

Netflix is really two systems glued together: a batch/offline ingest-and-encode pipeline, and an online, latency-critical playback path. Separating those two concerns up front is the single most important framing move in this interview.

Functional requirements

Ingest & transcodeA studio master is uploaded once and transcoded into an adaptive bitrate ladder across multiple resolutions and codecs.
Adaptive playbackThe player fetches a manifest and streams segments, switching bitrate as network conditions change - no rebuffer-worthy stalls.
Resume watchingPlayback position is saved per profile and resumes on any device, including mid-episode.
Catalog & licensingTitles are gated per subscription tier and per region based on content licensing rights.

Non-functional requirements

Startup latencyTime from pressing play to first frame should be well under 2 seconds worldwide.
Never bufferPlayback must degrade bitrate gracefully long before it drops frames or stalls.
Massive fan-out readsA single popular title is streamed by millions of concurrent viewers; encoding happens once, playback happens everywhere.
Durability of encodesA studio master and its renditions represent irreplaceable, expensive-to-redo compute; they must never be silently lost.
Explicitly out of scope Live sports/events streaming (a fundamentally different low-latency broadcast problem), content recommendation ranking models, and billing/payment processing are called out as extensions rather than core requirements, so the core design stays focused on ingest and playback.

2. Back-of-the-envelope capacity estimation

These numbers decide the shape of everything downstream: how much encoding compute is needed, how aggressively the CDN must cache, and how the watch-history write path must be batched to survive peak concurrency.

MetricAssumptionResulting estimate
Peak concurrent streams260M subscribers, ~15% actively streaming at prime-time peak~39M concurrent streams during the evening peak window
Peak CDN egress bandwidth~3.5 Mbps average bitrate per stream (mixed SD/HD/4K)39M × 3.5 Mbps ≈ 137 Tbps - only survivable because 99%+ is served from edge caches embedded in ISPs, not a central origin
New titles ingested~500 new titles/day across originals and licensed content500/day × ~15 renditions × 3 codecs (H.264/HEVC/AV1) ≈ 22,500 encode jobs/day
Encode storage growth~150 GB average across the full rendition ladder per title500 × 150GB ≈ 75 TB/day of new encoded assets, before origin replication
Watch-history writes39M concurrent streams, one progress heartbeat every 30s~1.3M heartbeat writes/sec - batched and buffered, never written synchronously per-second per stream
Why this matters The gap between "encode once" and "play billions of times" is the single number that justifies the architecture: transcoding is an expensive, parallelizable batch workload that tolerates minutes of latency, while playback is a latency-critical read path that must be served almost entirely from edge cache, never from origin.

3. High-level design (HLD)

The HLD splits cleanly into the ingest/encode pipeline (offline, write-heavy, cost-sensitive) and the playback path (online, read-heavy, latency-sensitive), connected only through the origin store and the catalog metadata service.

Content studiouploads master Ingest servicevalidate, chunk Transcoding fleetparallel encode jobs QC & packagingDRM, subtitles Origin storeS3, versioned Client playerTV / mobile / web Playback APIauth + manifest Catalog metadatatitles, licensing CDN edge (Open Connect)caches renditions Watch history svcresume position Event streamprogress, plays
Stateless servicesFast-path / DRM infraDurable storage & edgeAsync / metadata

What each box owns

Ingest service & transcoding fleet

The ingest service validates the studio master, splits it into chunks so a two-hour film can be encoded in parallel rather than as one long serial job, and enqueues one encode job per (rendition, codec, chunk) tuple. The transcoding fleet is a large pool of stateless, horizontally scalable workers - this workload is embarrassingly parallel and tolerant of minutes of latency, which is exactly why it runs on elastic batch/spot compute instead of always-on capacity.

QC, packaging, and the origin store

After encoding, an automated (and sometimes manual) QC pass checks for artifacts, sync issues, and missing subtitle tracks before a title is marked publishable. Packaging attaches DRM license metadata and multiplexes subtitle/audio tracks. The origin store is the durable, versioned source of truth for every rendition - it is written to once per title and read from constantly by the CDN, never directly by end-user devices at scale.

Playback API & CDN edge (Open Connect)

The Playback API authenticates the session, checks subscription tier and regional licensing, and returns a signed manifest listing available renditions. The actual video bytes are then requested from the nearest CDN edge node - Netflix's Open Connect appliances are physically embedded inside ISP networks specifically so the vast majority of bytes never cross the public internet backbone at all.

Watch history service & event stream

The player emits lightweight progress heartbeats (not per-second, batched every ~30s) to an event stream; a dedicated watch-history service consumes that stream and updates the "continue watching" position per profile. This is deliberately asynchronous and decoupled from the playback path - a slow watch-history write must never cause a rebuffer.

4. Detailed architecture diagram

The architecture diagram takes every HLD box and answers "how is this actually deployed at Netflix's scale?" - control-plane regions, the encoding farm's elasticity, and exactly how the CDN edge is embedded in ISP networks.

Client edge Device player (ABR client) Open Connect applianceinside ISP data center DNS / edge steering Playback API gatewayTLS + auth Control plane: us-east-1 Playback svc ×40 pods Catalog/licensing ×12 pods DRM license service Manifest cache (Redis) Encoding farm (elastic batch compute) Job scheduler / queue Encode workers ×1000s (spot) QC & packagingper-title ladder decisionscales to zero off-peak Origin storage tier S3 (multi-region) Rendition index pre-positioned to Open Connect ahead of release Watch-event pipeline Kafka topics Stream workers batched writes to Cassandra Watch history store Cassandra (wide-column) partitioned by profile_id
DecisionChoiceReasoning
CDN strategyOwn-built edge (Open Connect) embedded in ISPsAt this egress volume, paying third-party CDN transit rates is uneconomical; owning appliances placed inside ISP networks avoids most public-internet transit entirely.
Encoding computeElastic batch/spot fleet, scales to near-zero off-peakTranscoding is bursty (new releases) and parallelizable; paying for always-on dedicated capacity would waste money most of the day.
Watch history storageWide-column store (Cassandra), partitioned by profile_idAccess pattern is almost always "get/update this profile's recent history" - a partition-friendly key beats a relational join-heavy schema at this write volume.
Content pre-positioningPush popular titles to edge caches ahead of release, not reactivelyWaiting for organic cache misses on a major release would overwhelm origin bandwidth in the first hour; predictable releases are proactively warmed.

5. Sequence diagrams for the two critical flows

One flow is entirely offline and tolerant of latency (encoding); the other is online and cannot tolerate more than milliseconds of added delay (playback). The diagrams below show exactly where that boundary sits.

5.1 Video upload & transcoding pipeline

Studio Ingest svc Encode queue Encode workers Origin store 1. upload master (multipart) 2. validate + chunk into GOP segments 3. enqueue N encode jobs (rendition x codec x chunk) 4. dequeue job 5. encode chunk, upload rendition 6. ack job complete 7. all chunks done → stitch + QC 8. notify: title publishable

Step 3 fans a single upload out into thousands of independent, parallelizable encode jobs - this is what turns a two-hour film into an encoding job that finishes in minutes rather than hours. Step 6 is drawn as a synchronous ack only for job-completion bookkeeping; the actual encoded bytes in step 5 go straight to the origin store, not back through the queue, so large binary payloads never round-trip through the job broker.

5.2 Playback with adaptive bitrate streaming

Player Playback API CDN edge Event stream Watch history 1. press play (titleId, resume pos) 2. check license/tier, sign manifest 3. manifest (rendition URLs) 4. GET segment @ bitrate N 5. segment bytes 6. ABR: buffer low → drop to bitrate N-1 7. progress heartbeat (fire-and-forget, every 30s) 8. async consume → upsert position

Steps 4-6 repeat continuously for the whole runtime of the title, entirely between the player and the CDN edge - the Playback API is consulted once per session, not once per segment, which is exactly why it can stay stateless and cheap relative to the CDN's byte volume. Step 6 is the client-side ABR heuristic (buffer occupancy and measured throughput) deciding to step down a rendition before the buffer empties; step 7 is fire-and-forget so a slow watch-history write can never cause a stall.

6. Entity-relationship (ER) diagram and schema

The data model has to answer: how many renditions does one video own, how is per-profile resume position looked up instantly, and how does a subscription gate which titles and which bitrate ceiling a profile is entitled to.

videos PK id BIGINT title VARCHAR runtime_sec INT license_regions JSON published_at TIMESTAMP status ENUM encodings PK id BIGINT FK video_id BIGINT resolution VARCHAR codec ENUM bitrate_kbps INT storage_uri TEXT drm_key_id VARCHAR watch_history PK id BIGINT FK profile_id BIGINT FK video_id BIGINT position_sec INT updated_at TIMESTAMP subscriptions PK id BIGINT FK account_id BIGINT plan_tier ENUM 1N 1N 1N one video has many encodings and many watch_history rows; one subscription tier gates max bitrate/resolution

Key modeling decisions

encodings is a child table, never a JSON blob on videosRenditions are added/re-encoded independently (a new AV1 pass doesn't touch existing HEVC rows), and QC status is tracked per rendition, not per title.
watch_history keyed on (profile_id, video_id)Not (account_id, video_id) - each profile on a shared household account needs an independent resume position, which is why profile, not account, is the partition key.
subscriptions carries plan_tier, not a raw bitrate capThe Playback API resolves plan_tier to a max resolution/bitrate at request time, so a pricing-tier definition change never requires a data migration.
NoSQL for watch_history at scaleA wide-column store (Cassandra) keyed on profile_id scales the write-heavy heartbeat path horizontally without cross-partition transactions.
Storage choiceUse whenWatch out for
Relational (Postgres/MySQL) for videos, encodings, subscriptionsCatalog and billing data is comparatively low-volume and benefits from strong consistency and joins (a video's full rendition list, a plan's entitlements).Not designed for the extreme write-fan-out of playback telemetry.
Wide-column (Cassandra/DynamoDB) for watch_historyAccess pattern is always "read/write this profile's rows" at massive concurrent write volume.Cross-profile analytics queries (e.g. "most-resumed titles") need a separate batch/OLAP pipeline, not ad hoc queries on this store.

7. Deep dives interviewers actually probe

How does client-side adaptive bitrate (ABR) selection actually work?

The player continuously measures two signals: current buffer occupancy (how many seconds of video are already downloaded and waiting) and recent segment download throughput. A buffer-based ABR algorithm steps down a rendition well before the buffer empties (avoiding a stall), and steps up only after sustaining healthy buffer levels for several segments (avoiding oscillation). This logic lives entirely on the client - the server just exposes the rendition ladder in the manifest and never dictates bitrate.

Per-title encoding ladder vs a fixed ladder for every video - is it worth the complexity?

A fixed ladder (e.g. always encode 240p/480p/720p/1080p/4K at fixed bitrates) is simple but wastes bits on visually simple content (animation, talking-head interviews) and under-serves visually complex content (fast action, film grain) at the same bitrate. Per-title encoding analyzes each source's complexity and picks a custom bitrate/resolution ladder, typically cutting average bitrate 20-50% at equal perceived quality - worth it given the CDN egress cost at Netflix's scale, but it roughly doubles encoding pipeline complexity and compute cost per title.

How is "continue watching" kept consistent across devices without conflicts?

Each device sends periodic heartbeats with its own local playback position; the watch-history service applies a last-write-wins update keyed by (profile_id, video_id) using the heartbeat's server-received timestamp, not client clock time (client clocks drift and can't be trusted for ordering). A user rarely watches the same title simultaneously on two devices, so last-write-wins is an acceptable simplification rather than needing full conflict resolution.

How does the CDN decide what to cache before anyone has watched it yet?

Popular and newly-released titles are proactively pushed ("pre-positioned") to Open Connect appliances during off-peak hours ahead of their release window, based on regional popularity predictions - waiting for organic cache misses on a hit show's midnight release would otherwise create a massive, predictable origin traffic spike in the first hour. Long-tail catalog titles rely on standard reactive LRU caching instead, since pre-positioning every title everywhere isn't economical.

What is the single biggest bottleneck as this scales 10x?

Not playback bandwidth - CDN edge capacity scales roughly linearly by adding more appliances inside more ISPs. The real bottleneck becomes encoding pipeline throughput during a burst of same-day releases (e.g. a major franchise premiere plus several new originals landing at once): thousands of parallel encode jobs competing for the same elastic compute pool can delay QC and publishing. The fix is prioritized job scheduling (release-date-aware queues) rather than simply adding more workers, since spot capacity itself has regional limits.

8. Summary: what a strong answer covers

Separated batch encode from online playbackJustified every number with a calculationExplained per-title encoding trade-offs Named the CDN strategy and why it's owned, not rentedMade watch history async and non-blockingCompared SQL vs wide-column honestly
Interview tip When asked to design Netflix, the strongest signal is recognizing this is two systems, not one: an offline, cost-optimized, embarrassingly parallel encoding pipeline, and an online, latency-sacred playback path that must be servable almost entirely from edge cache - and being explicit about which trade-offs belong to which side.
No comments
Leave a Comment