Design Instagram (High-Level Design)
High-level design of Instagram: photos in blob storage behind a CDN, lightweight metadata and follow graph in a database, feeds via fan-out on write with a hybrid pull path for celebrities, plus async like/comment counters.
🟠High-Level Design · Case Study · Senior
"Design Instagram" is a classic because it combines two big problems in one: storing and serving huge volumes of photos, and generating a personalised feed for hundreds of millions of users. It's read-heavy, media-heavy, and celebrity-skewed — a perfect stage to show off caching, CDNs, and fan-out. Let's design it.
Step 1 — Requirements
- Functional: upload a photo (with caption); follow/unfollow users; view a home feed of posts from people you follow; like & comment; view a user's profile grid.
- Non-functional: very read-heavy (feed views ≫ posts), low-latency feed & image load, highly available, eventually consistent is fine (a like taking a second to appear is OK).
Step 2 — Back-of-envelope estimation
🟠Say 500M daily active users, each opening the feed ~10×/day → ~5B feed reads/day ≈ 60K reads/sec (peaks several ×). If 5% post once/day → 25M photos/day ≈ 300 writes/sec — so reads dominate writes by ~200:1. At ~2 MB/photo that's ~50 TB of new images per day. Two takeaways: optimise hard for reads (cache + CDN), and images need cheap, massive object storage, not a database.
Step 3 — API & data model
🟠A thin REST/gRPC API: POST /photos (upload), GET /feed, POST /follow/{userId}, POST /photos/{id}/like. Split storage by data type:
- Images → blob store (S3) + CDN. Never store binaries in the DB; store a URL.
- Metadata → DB:
Post(id, userId, imageUrl, caption, createdAt),Follow(followerId, followeeId),Like(userId, postId). The follow graph and post metadata are small and relational-ish; likes/counts scale better in a key-value store.
Step 4 — Architecture
Upload path: client uploads the image to the upload service → blob store; the CDN caches it near users so image loads are fast worldwide. Read path: the feed service returns a precomputed list of post IDs from the feed cache, hydrates metadata, and the client pulls images straight from the CDN.
Step 5 — The core problem: feed generation
🔴 Same fan-out trade-off as a news feed:
- Fan-out on write (push): when you post, push the post ID into every follower's cached feed list. Feed reads are then instant (just read your list). Great for the 99% of users.
- Fan-out on read (pull): build the feed at read time by querying who you follow. Cheaper writes, slower reads.
- The celebrity problem: pushing to 100M followers on every post is insane. Hybrid: push for normal users, and for celebrities pull their recent posts at read time and merge them in. This is the key insight interviewers want.
Step 6 — Scaling & deep dives
🔴 Round it out: serve all images via CDN (most bytes never touch your servers); cache hot feeds and profiles in Redis; shard metadata by user ID; store like/comment counts as denormalised counters (updated async via a queue) so you never COUNT(*) millions of rows; generate multiple image resolutions on upload for different screens. Eventual consistency on counts and feed ordering is an acceptable trade for the scale.
The interview-ready walkthrough
"It's read-heavy and media-heavy, so I split storage: images in a blob store behind a CDN, lightweight metadata + follow graph in a database. Feeds are precomputed via fan-out on write into a per-user feed cache, with a hybrid pull path for celebrities to avoid fan-out explosions. I'd cache hot feeds/profiles, shard by user, keep like/comment counts as async-updated counters, and serve every image from the CDN. Eventual consistency is fine here." That covers storage split, the feed trade-off, and the celebrity fix — the three things they're probing."
What to read next
- Design a News Feed — the fan-out problem in depth
- Design YouTube — the same media-at-scale, for video
- CDN · Blob/Object Storage — the media backbone
- ← The complete System Design guide (hub)