High‑Level Design of Netflix

Backend Fundamentals · System Design · 9 min read

1. What problem does this solve?

Motivation
A streaming platform like Netflix must deliver video content to millions of users worldwide with minimal latency, high reliability, and personalized experiences. The core problem is how to serve large amounts of media, scale to global traffic, and keep the system responsive and cost‑effective.

What problem exists

  • Massive data volume – hundreds of terabytes of video, metadata, logs, and user interactions.
  • Global distribution – users in every continent, each with different network conditions.
  • Dynamic content – new titles added daily, recommendations changing in real time.
  • High availability – downtime costs revenue and brand trust.
  • Personalization – recommendations, ads, and UI must adapt to each user.

Why the problem matters

  • User experience: buffering or missing content leads to churn.
  • Revenue: subscription fees are the primary income; any service degradation can reduce subscriptions.
  • Cost: inefficient architecture can balloon cloud spend.

What happens if this concept is not used

Without a well‑architected system, the service would:

  • Fail to scale under load spikes (e.g., new releases).
  • Experience high latency or outages.
  • Be unable to serve content globally.
  • Lack personalization, hurting engagement.

Where this concept appears in real backend systems

  • CDNs (e.g., Akamai, CloudFront) for edge caching.
  • Microservice architectures for decoupling features.
  • Event‑driven pipelines (Kafka, Kinesis) for real‑time analytics.
  • Recommendation engines (Spark, TensorFlow) for personalization.
  • Distributed databases (Cassandra, DynamoDB) for high write throughput.

2. Mental model

Simple analogy
Think of Netflix as a global library network:

  • Books = video files.
  • Central library = master storage (object store).
  • Branch libraries = CDN edge nodes.
  • Librarians = microservices (catalog, recommendation, billing).
  • Readers = users watching on devices.
  • Catalog system = search & recommendation engine.
  • Book delivery = adaptive streaming (HLS/DASH).

Just as a library network copies popular books to branches to reduce travel time, Netflix copies popular videos to edge caches to reduce latency.

Precise engineering model

User → API Gateway → Auth Service
          ↓
      Catalog Service
          ↓
      Recommendation Service
          ↓
      Streaming Service
          ↓
      CDN Edge (Cache)
          ↓
      Video Storage (S3/Glacier)
  • API Gateway routes requests and handles rate limiting.
  • Auth Service validates tokens.
  • Catalog stores metadata in PostgreSQL.
  • Recommendation consumes user events from Kafka, updates models in Redis.
  • Streaming serves HLS segments from CDN; if cache miss, fetches from S3.
  • CDN caches segments at the edge; invalidates on new releases.

3. Deep explanation

Internals

LayerResponsibilityTypical Tech
ClientUI, playbackReact, Swift, Kotlin
API GatewayRouting, auth, rate limitingExpress, Kong, NGINX
Auth ServiceToken issuance & validationJWT, OAuth2
Catalog ServiceMetadata CRUDPostgreSQL, ElasticSearch
Recommendation ServiceReal‑time scoringKafka, Redis, TensorFlow
Streaming ServiceSegment deliveryHLS/DASH, CDN
StorageDurable video storageS3, Glacier
CDNEdge cachingCloudFront, Akamai
AnalyticsEvent ingestionKafka, Flink
MonitoringMetrics, logsPrometheus, Grafana, ELK

Important terminology

  • Microservice – independently deployable unit.
  • Event‑driven – services react to events via message queues.
  • CDN – Content Delivery Network, edge cache.
  • Adaptive streaming – HLS/DASH segments at multiple bitrates.
  • Cache invalidation – removing stale data from CDN.
  • Back‑pressure – handling overload by slowing producers.

Trade‑offs

DecisionProsCons
Monolith vs MicroservicesSimpler deploymentHarder to scale individual parts
SQL vs NoSQLStrong consistencyLimited horizontal scaling
Cache at CDN vs OriginLow latencyCache invalidation complexity
Real‑time vs Batch recommendationsFreshnessHigher compute cost

Failure modes

  • Cache miss storm: sudden surge of requests to origin after cache invalidation.
  • Auth token revocation lag: revoked tokens still accepted until cache expires.
  • Event backlog: Kafka lag causing recommendation delay.
  • CDN outage: edge nodes down → fallback to origin, higher latency.

Limitations

  • Cold start: new microservices take time to spin up.
  • Data consistency: eventual consistency in distributed caches can lead to stale recommendations.
  • Cost: CDN bandwidth and storage can dominate spend.

Where this concept fits in a backend architecture

High‑level design is the blueprint that defines services, data flows, and infrastructure. It sits above the implementation layer (code, databases) and below the operations layer (CI/CD, monitoring). It informs decisions about:

  • Service boundaries
  • Data partitioning
  • API contracts
  • Deployment topology
  • Observability: metrics from each service feed into a central dashboard.
  • Security: JWT validation at gateway; TLS everywhere.
  • Scalability: horizontal scaling of services, auto‑scaling of CDN.
  • Reliability: circuit breakers, retries, graceful degradation.

4. How it works

Step‑by‑step flow

  1. User request: GET /watch/12345 from a web client.
  2. API Gateway receives request, authenticates JWT, forwards to Streaming Service.
  3. Streaming Service checks CDN cache for segment 12345/segment_01.ts.
  4. If cache hit: CDN serves segment directly.
  5. If cache miss: CDN fetches from Origin (S3) via Streaming Service.
  6. Streaming Service streams HLS playlist to client.
  7. Client requests next segment; steps 3‑6 repeat.
  8. User interaction (e.g., click “Add to Watchlist”) triggers event to Kafka.
  9. Recommendation Service consumes event, updates user profile in Redis.
  10. Catalog Service updates metadata in PostgreSQL; triggers CDN invalidation.

Mermaid diagram

sequenceDiagram
    participant U as User
    participant AG as API Gateway
    participant SS as Streaming Service
    participant CDN as CDN Edge
    participant S3 as Object Storage
    participant K as Kafka
    participant RS as Recommendation Service
    participant PG as PostgreSQL

    U->>AG: GET /watch/12345
    AG->>SS: Forward request
    SS->>CDN: Check cache
    alt Cache hit
        CDN->>U: Serve segment
    else Cache miss
        CDN->>SS: Fetch from origin
        SS->>S3: GET segment
        S3->>SS: Return segment
        SS->>CDN: Cache segment
        CDN->>U: Serve segment
    end
    U->>AG: POST /watchlist
    AG->>K: Produce event
    K->>RS: Consume event
    RS->>Redis: Update profile
    RS->>PG: Update catalog
    PG->>CDN: Invalidate cache

5. Practical implementation

Below is a minimal Node.js example that demonstrates:

  • API Gateway with Express
  • Auth middleware
  • Streaming endpoint that proxies to S3
  • Redis cache for metadata
  • Kafka producer for user events

Prerequisites: Docker, Docker‑Compose, Node 18, Redis, Kafka, MinIO (S3 compatible)

docker-compose.yml

version: "3.8"
services:
  redis:
    image: redis:7
    ports:
      - "6379:6379"

  kafka:
    image: bitnami/kafka:3
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"

  zookeeper:
    image: bitnami/zookeeper:3
    environment:
      ALLOW_ANONYMOUS_LOGIN: "yes"
    ports:
      - "2181:2181"

  minio:
    image: minio/minio
    command: server /data
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123
    ports:
      - "9000:9000"

src/index.ts

import express from 'express';
import jwt from 'jsonwebtoken';
import { createClient } from 'redis';
import { Kafka } from 'kafkajs';
import fetch from 'node-fetch';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';

const app = express();
app.use(express.json());

// ---------- Config ----------
const JWT_SECRET = 'supersecret';
const REDIS_URL = 'redis://localhost:6379';
const KAFKA_BROKER = 'kafka:9092';
const S3_ENDPOINT = 'http://minio:9000';
const S3_BUCKET = 'videos';

// ---------- Clients ----------
const redis = createClient({ url: REDIS_URL });
redis.on('error', console.error);

const kafka = new Kafka({ brokers: [KAFKA_BROKER] });
const producer = kafka.producer();

const s3 = new S3Client({
  endpoint: S3_ENDPOINT,
  region: 'us-east-1',
  credentials: { accessKeyId: 'minio', secretAccessKey: 'minio123' },
});

// ---------- Middleware ----------
function auth(req: express.Request, res: express.Response, next: express.NextFunction) {
  const auth = req.headers.authorization;
  if (!auth) return res.status(401).send('Missing token');
  const token = auth.split(' ')[1];
  try {
    const payload = jwt.verify(token, JWT_SECRET);
    (req as any).user = payload;
    next();
  } catch {
    res.status(401).send('Invalid token');
  }
}

// ---------- Routes ----------
app.get('/watch/:id', auth, async (req, res) => {
  const videoId = req.params.id;
  const segment = 'segment_01.ts'; // For demo, always same

  // 1. Check CDN cache (here we just proxy to S3)
  const key = `${videoId}/${segment}`;
  try {
    const cmd = new GetObjectCommand({ Bucket: S3_BUCKET, Key: key });
    const data = await s3.send(cmd);
    // Stream to client
    res.setHeader('Content-Type', 'video/mp2t');
    data.Body.pipe(res);
  } catch (e) {
    res.status(404).send('Segment not found');
  }
});

app.post('/watchlist', auth, async (req, res) => {
  const { videoId } = req.body;
  const userId = (req as any).user.sub;

  // 2. Persist to Redis (demo only)
  await redis.hSet(`watchlist:${userId}`, videoId, Date.now());

  // 3. Produce event to Kafka
  await producer.connect();
  await producer.send({
    topic: 'user-events',
    messages: [{ value: JSON.stringify({ userId, videoId, action: 'add' }) }],
  });
  await producer.disconnect();

  res.send({ status: 'ok' });
});

app.listen(3000, () => console.log('API Gateway listening on 3000'));

Explanation of key lines

  • auth middleware validates JWT and attaches user payload.
  • /watch/:id streams a video segment from S3; in production this would hit a CDN.
  • /watchlist updates Redis and publishes an event to Kafka for downstream services.

Run: docker compose up then npm run dev (after npm i).


6. Production considerations

ConcernWhat to doWhy
ScalabilityHorizontal scaling of services, auto‑scaling groups, CDN edge nodesHandle traffic spikes, global load
ReliabilityCircuit breakers, retries, graceful degradation, multi‑AZ deploymentsAvoid single points of failure
SecurityTLS everywhere, JWT revocation, rate limiting, DDoS protectionProtect user data, prevent abuse
ObservabilityDistributed tracing (OpenTelemetry), metrics (Prometheus), logs (ELK)Detect issues fast
PerformanceEdge caching, adaptive bitrate, CDN pre‑fetchingReduce latency, bandwidth
Error handlingIdempotent operations, dead‑letter queues, alertingEnsure data consistency
Resource usageSpot instances for batch jobs, cache eviction policiesCost optimization
Operational concernsCI/CD pipelines, blue/green deployments, canary releasesMinimize downtime
Failure recoveryBackup of S3 objects, Kafka replication, disaster recovery planData durability
DeploymentContainerized services, Kubernetes or ECS, Helm chartsConsistent environments

7. Common mistakes

MistakeWhy it’s bad
Hard‑coding secretsExposes credentials, violates principle of least privilege
Ignoring cache invalidationUsers see stale content, recommendation drift
Over‑optimistic cachingCache data that changes frequently → stale recommendations
Single‑point auth serviceBottleneck, single failure
No retry/back‑offTransient network failures cause cascading errors
Not monitoring Kafka lagRecommendation engine stalls, user experience suffers
Using SQL for high‑write workloadsBottleneck, poor horizontal scaling
Skipping rate limitingAPI abuse leads to resource exhaustion

8. Senior engineer perspective

What changes at scale

  • Service granularity: split monolith into dozens of microservices (catalog, recommendation, billing, analytics).
  • Data partitioning: sharding user data across PostgreSQL clusters, using read replicas.
  • Event sourcing: store all user actions in Kafka for audit and replay.
  • CDN orchestration: programmatic cache invalidation via APIs, edge compute for personalization.
  • Observability stack: distributed tracing across services, anomaly detection on metrics.

Design decisions

DecisionTrade‑offsBottlenecksMonitoring
Use Kafka vs. RabbitMQKafka scales better for high throughputKafka cluster maintenanceKafka lag, topic health
Cache in Redis vs. MemcachedRedis supports persistence, Lua scriptsRedis memory limitsMemory usage, eviction
CDN edge vs. originEdge reduces latencyEdge cache invalidation complexityCache hit ratio
SQL vs. NoSQL for catalogStrong consistency vs. horizontal scalingSQL write lock contentionQuery latency
Batch vs. real‑time recommendationsBatch reduces compute costReal‑time freshnessModel training time

Bottlenecks

  • CDN cache miss storms after new release.
  • Kafka partition skew leading to uneven consumer load.
  • Database connection pool exhaustion under heavy write traffic.

Monitoring

  • Latency per service endpoint.
  • Cache hit/miss ratios.
  • Kafka consumer lag.
  • S3 read/write throughput.
  • CDN error rates.

When NOT to use this approach

  • Small startup with < 10k users: monolith + single CDN may suffice.
  • Low‑latency gaming: CDN caching may introduce unacceptable latency; use edge compute.
  • Highly regulated data: need stricter data residency; may require custom storage.

9. Interview questions

1BeginnerWhat is a CDN and why is it important for a streaming service?
Answer
: A CDN caches content at edge locations to reduce latency and bandwidth costs; it ensures users get fast, reliable streams.
2BeginnerExplain the difference between a monolith and microservices.
Answer
: A monolith bundles all functionality into one deployable unit; microservices split functionality into independently deployable services, improving scalability and fault isolation.
3SeniorHow would you design a recommendation engine that can scale to millions of users while keeping latency low?
Answer
: Use event streaming (Kafka) to capture user interactions, process them in real time with stream processors (Kafka Streams, Flink), store user embeddings in Redis for fast lookup, and batch‑train models offline on GPU clusters.
4SeniorDescribe how you would handle cache invalidation after a new video release.
Answer
: Publish an event to a “content‑update” topic; all CDN edge nodes subscribe and purge relevant keys; optionally use versioned URLs to avoid stale cache.
5Scenario/DebuggingA user reports buffering after a new episode release. What steps would you take to diagnose and fix the issue?
Answer
:
  • Check CDN cache hit ratio for the episode.
  • Inspect S3 read latency and throughput.
  • Verify Kafka consumer lag for the ingestion pipeline.
  • Look at streaming service logs for errors.
  • If cache miss storm, trigger pre‑fetch or increase edge capacity.
  • Roll back to previous version if necessary.

10. Hands‑on task

Task: Implement a watchlist microservice that:

  1. Exposes POST /watchlist to add a video.
  2. Stores the watchlist in Redis.
  3. Publishes an event to Kafka.
  4. Provides GET /watchlist to retrieve the list.

Steps

  • Fork the repository.
  • Add a new folder watchlist-service.
  • Implement the API using Express, Redis, and Kafka (use the code skeleton above).
  • Write unit tests for the endpoints.
  • Deploy locally with Docker Compose and verify end‑to‑end flow.

11. Quick revision

  • Netflix is a global library network of microservices, CDNs, and event pipelines.
  • CDN reduces latency by caching media at edge nodes.
  • API Gateway handles auth, routing, and rate limiting.
  • Auth Service issues JWTs; validate at gateway.
  • Catalog Service stores metadata in PostgreSQL; searchable via ElasticSearch.
  • Recommendation Service consumes Kafka events, updates Redis, and serves real‑time scores.
  • Streaming Service serves HLS/DASH segments from S3 via CDN.
  • Kafka is the backbone for real‑time event ingestion.
  • Redis is used for fast lookups (watchlist, recommendations).
  • Observability: Prometheus metrics, Grafana dashboards, distributed tracing.
  • Failure modes: cache miss storms, Kafka lag, CDN outages.
  • Scalability: horizontal scaling, auto‑scaling groups, multi‑AZ.
  • Security: TLS, JWT, rate limiting, DDoS protection.
  • Common mistakes: hard‑coding secrets, ignoring cache invalidation, over‑optimistic caching.

12. References