SYSTEM_DESIGN

System Design: Instagram

Deep dive into designing Instagram at scale, covering photo/video uploads, feed generation, follower graphs, and CDN strategies used by systems serving 2 billion users.

18 min readUpdated Jan 15, 2025
system-designinstagramsocial-mediacdn

Requirements

Functional Requirements:

  • Users can upload photos and short videos
  • Users can follow/unfollow other users
  • Users see a personalized feed of posts from followed accounts
  • Users can like, comment, and share posts
  • Users can search for content and other users
  • Support for Stories (ephemeral 24-hour content)

Non-Functional Requirements:

  • 2 billion MAU, 500 million DAU; handle 100M+ photo uploads per day
  • Feed load latency under 200ms (p99)
  • 99.99% availability; content must never be permanently lost
  • Eventual consistency acceptable for feed; strong consistency for follower counts

Scale Estimation

With 500M DAU each viewing ~20 feed items, that's 10 billion feed reads per day — roughly 115K reads/sec. Writes: 100M uploads/day = ~1,160 writes/sec. Average photo size 3MB compressed → 300TB new storage per day. Videos average 50MB → add another 500TB/day for video content. Total storage after 5 years exceeds 1.5 exabytes, requiring distributed object storage and aggressive CDN caching.

High-Level Architecture

Instagram's architecture separates the write path from the read path. The write path handles media ingestion: clients upload to an Upload Service which pushes raw bytes to S3-compatible object storage (Instagram uses a custom system built on top of Cassandra and a distributed blob store). A Media Processing Service (running on a GPU-backed fleet) transcodes videos into multiple resolutions and generates thumbnails, storing results back in object storage. Metadata (user ID, caption, timestamp, location) is written to a Postgres cluster (sharded by user ID) and replicated asynchronously to a Cassandra ring for feed reads.

The read path is powered by a Fan-Out Service. When a user posts, the service pushes the post ID into the follower feeds stored in Redis sorted sets (fan-out on write for users with <10K followers). For celebrities with millions of followers, a hybrid fan-out on read strategy is used: their posts are fetched at read time and merged with the precomputed feed. The API Gateway handles authentication via JWT tokens, rate limiting, and routes to the appropriate microservice.

Core Components

Media Upload Service

The Upload Service accepts multipart form uploads and streams bytes directly to S3 using pre-signed URLs, avoiding the application tier as a bottleneck. Once the upload completes, a Kafka event is emitted triggering the transcoding pipeline. The service returns a pending post ID immediately for optimistic UI rendering.

Feed Generation Service

For the average user (< 10K followers), feed generation is push-based: every new post triggers a write to each follower's Redis sorted set keyed by feed:{user_id}, scored by timestamp. For celebrities, a pull-based merge happens at read time. Feed items are paginated using cursor-based pagination — the cursor encodes the last post timestamp, not an offset, to handle concurrent insertions.

Search & Discovery Service

Search is powered by Elasticsearch, indexing user profiles, hashtags, and caption text. The Explore page uses a recommendation engine built on graph embeddings (user-item interaction matrices factored via ALS) served from a feature store. Results are cached in Redis with a 5-minute TTL.

Database Design

User and post metadata lives in a sharded PostgreSQL cluster (Vitess for horizontal sharding) partitioned by user_id. The Posts table contains post_id, user_id, media_url, caption, created_at, and a JSONB column for metadata. A separate Cassandra cluster stores the social graph (followers/following) using a wide-column model: follows table with partition key follower_id and clustering key followee_id. This allows O(1) lookups for 'who does user X follow' and efficient scans.

Media binaries are stored in a distributed object store (S3-compatible). A CDN (Cloudflare or Fastly) sits in front with cache-control headers set to immutable for processed media since URLs are content-addressed (hash of the content). Hot media is cached at CDN edge; cold media is served from origin with lazy loading.

API Design

  • POST /api/v1/posts — Upload a new post; multipart form with media + metadata; returns post_id
  • GET /api/v1/feed?cursor={timestamp}&limit=20 — Fetch paginated feed for the authenticated user
  • POST /api/v1/posts/{post_id}/likes — Like a post; idempotent with upsert semantics
  • GET /api/v1/users/{user_id}/posts?cursor={id}&limit=20 — Fetch a user's profile grid

Scaling & Bottlenecks

The feed fan-out for high-follower accounts is the primary bottleneck. Instagram uses a tiered approach: users with >1M followers get their posts served via pull-merge at read time. Redis clusters for feed storage are sharded by user_id using consistent hashing with virtual nodes, allowing seamless rebalancing. Each Redis node is replicated 3x for durability. The Kafka pipeline decouples write amplification — a single post triggers async fan-out workers rather than synchronous writes.

Media delivery is handled by a multi-tier CDN: Fastly at the edge with a 7-day TTL for processed images, and a regional cache tier for long-tail content. Images are served in WebP/AVIF format with resolution negotiation based on client device. The object storage tier uses erasure coding (Reed-Solomon 14+4) for durability without the overhead of full 3x replication. Database read replicas in multiple regions handle geographic distribution of reads.

Key Trade-offs

  • Fan-out on write vs read: Write fan-out gives fast reads but high write amplification for celebrities — hybrid approach balances both
  • Eventual consistency for feeds: Accepting stale feeds (a few seconds delay) dramatically reduces write latency and simplifies the fan-out architecture
  • Content-addressed media URLs: Using hash-based URLs enables permanent CDN caching (immutable cache headers) but requires a redirect layer for deleted content
  • Cassandra for social graph over SQL: Cassandra's wide-column model handles the massive fan-out of follower lists more efficiently than relational joins at this scale

GO DEEPER

Master this topic in our 12-week cohort

Our Advanced System Design cohort covers this and 11 other deep-dive topics with live sessions, assignments, and expert feedback.