system-design · intermediate
Design Instagram — Photos, Feed, and Fan-Out
Start here
Design Instagram (simplified) means designing a service where users:
- Upload photos
- Follow other users
- See a home feed of recent posts from people they follow
- Open a post and view the image quickly worldwide
What you will learn
- Clarify MVP vs out-of-scope features (Stories, Reels, DMs).
- Estimate storage and QPS.
- Design upload and view paths with object storage + CDN.
- Compare fan-out on write vs fan-out on read for feeds.
- Handle celebrity accounts without melting the system.
- Discuss caching, ranking hooks, and failures.
What you should know first
| Topic | Why |
|---|---|
| Answering framework | Interview structure |
| Caching 101 | Hot feed and media metadata |
| Fan-out write vs read | Feed generation |
| CDN | Image delivery |
Words you need before we begin
| Term | Plain English |
|---|---|
| Object storage | Blob store for image bytes (S3-style). |
| Feed / timeline | Ordered list of post ids for a user’s home screen. |
| Fan-out on write | On post, push post id into followers’ feed stores. |
| Fan-out on read | On feed open, pull recent posts from followees and merge. |
| Celebrity / hot user | Account with huge fan-out cost on write. |
| CDN | Edge caches for static media. |
| Presigned URL | Time-limited upload/download URL to object storage. |
Requirements (interview style)
Functional (MVP)
- Register/login (auth can be shallow)
- Upload photo + caption
- Follow / unfollow
- Home feed (reverse chronological is fine for MVP)
- View post + image
Out of scope initially
- Recommendations, ads, Stories, live video, full search
Non-functional
- Uploads reliable; views low-latency globally
- Feed freshness seconds–minutes
- High availability for reads
Example scale (state assumptions)
- 500M DAU, 2 posts/user/day average → ~10k posts/s average (burst higher)
- Read:write on feed much higher than upload
- Images: 200 KB average after processing
High-level design
flowchart LR
App[Mobile app] --> API[API gateway]
API --> Upload[Upload service]
API --> Feed[Feed service]
API --> Graph[Graph service]
Upload --> Obj[(Object storage)]
Upload --> Meta[(Post metadata DB)]
Graph --> GDB[(Follow graph store)]
Feed --> FeedStore[(Feed cache / store)]
App --> CDN[CDN] --> Obj
Step-by-step core design
Step 1 — Upload path
- Client requests upload session.
- API returns presigned URL to object storage.
- Client uploads bytes directly (API not a bandwidth bottleneck).
- Client confirms; service writes post metadata (userId, objectKey, caption, createdAt).
- Async workers generate thumbnails / variants.
Step 2 — Follow graph
Store edges follower → followee in a graph-friendly store or sharded SQL/NoSQL. Query: list followees for user U; list followers for fan-out.
Step 3 — Feed generation options
| Approach | How | Pros | Cons |
|---|---|---|---|
| Fan-out on write | Push post id to each follower’s timeline list | Fast reads | Celebrity posts expensive |
| Fan-out on read | Merge latest posts from followees at read | Cheap writes | Slow/complex reads |
| Hybrid | Write fan-out for normal users; read merge for celebs | Balanced | More logic |
Interview recommendation: hybrid.
Step 4 — Feed storage
Redis/streams or Cassandra-style timeline: feed:userId → [postId…] capped (e.g. last 1000). On open, hydrate post metadata from cache/DB; images via CDN URLs.
Step 5 — View path
Metadata cache by postId; image URL points to CDN → origin object store.
Step 6 — Celebrity path
If follower count > threshold, skip push fan-out; pull their posts at read time and merge into feed.
Complete worked example narrative
User A (1k followers) posts. System writes metadata, then enqueues fan-out job that pushes postId into 1k feed lists (batched workers). User B opens home: read feed list from Redis, batch-get post metadata, return JSON with CDN image URLs.
User C (20M followers) posts. System marks celeb path: no 20M pushes. Followers merge C’s recent posts when building feed.
Failure modes
| Mode | Impact | Mitigation |
|---|---|---|
| Fan-out lag | Feed not fresh | Worker scale; show “updating” |
| Hot celebrity write | Job storm | Hybrid threshold |
| Object store outage | Upload fail | Retry; multi-region later |
| Cache miss storm | DB load | Soft TTL; single-flight |
| Graph DB hot partition | Follow ops slow | Shard by userId |
Trade-offs
| Choice | Benefit | Cost |
|---|---|---|
| Chronological feed | Simple | Less engagement than ranked |
| Ranked feed | Product quality | Ranking infra + fairness issues |
| Strong consistency feed | Simpler mental model | Harder at scale |
| Eventual feed | Scale | Users may not see post instantly |
Common interview mistakes
- Serving image bytes through the app server.
- Ignoring celebrity fan-out.
- Only saying “use Kafka” without feed model.
- No CDN for media.
- Perfect ranking before basic timeline works.
Check your understanding
- Why presigned uploads?
- Fan-out on write vs read in one sentence each?
- How do celebrity accounts change the design?
- What is stored in a feed list entry minimally?
- Where do thumbnails get created?
Practice
- Estimate storage for 100M new photos/day at 200 KB.
- Draw sequence for upload + fan-out.
- Pick a celebrity threshold and justify.
- Design cache keys for post metadata.
- Mock a 40-minute interview aloud.
Deeper production notes
Idempotent fan-out
Workers must tolerate retries without duplicating feed entries unboundedly—use set semantics or dedupe keys.
Privacy
Private accounts need authorization on graph edges and feed assembly—not only on upload.
Multi-region
Media CDN is global; metadata and fan-out often start single-region primary with eventual expansion.
Additional teaching scenarios
Scenario A — 10× peak
Which component saturates first? What is the first mitigation?Scenario B — partial outage
A dependency is down for 30 minutes. What do users still get, and what is degraded?Scenario C — interview wrap
Summarize the design in five sentences: requirements, MVP, scale lever, failure mode, trade-off.Revision summary
- Separate bytes (object store + CDN) from metadata.
- Feed is a fan-out problem—use hybrid for celebrities.
- Optimize reads; async the heavy write fan-out.
- Discuss freshness, cache, and failure explicitly.
Glossary
| Term | Definition |
|---|---|
| Fan-out | Delivering one post to many followers’ views. |
| Timeline store | Per-user list of post ids for home feed. |
| Presigned URL | Scoped temporary object-storage access. |
Abbreviations and terminology
- CDN — Content Delivery Network
- DAU — Daily active users
- QPS — Queries per second
What to learn next
Extra teaching notes
When you apply this lesson, write the user-visible success metric first, then the failure mode you fear most. Design the smallest mechanism that protects that metric under partial failure. Prefer explicit timeouts, idempotency, and ownership over adding more infrastructure boxes.
In interviews or design reviews, narrate assumptions, request paths, and trade-offs out loud. A correct-enough design with clear failure handling beats a buzzword diagram without numbers. Revisit the worked example and restate it for a different domain to prove you own the ideas, not the template wording.
Extra teaching notes
When you apply this lesson, write the user-visible success metric first, then the failure mode you fear most. Design the smallest mechanism that protects that metric under partial failure. Prefer explicit timeouts, idempotency, and ownership over adding more infrastructure boxes.
In interviews or design reviews, narrate assumptions, request paths, and trade-offs out loud. A correct-enough design with clear failure handling beats a buzzword diagram without numbers. Revisit the worked example and restate it for a different domain to prove you own the ideas, not the template wording.
Extra teaching notes
When you apply this lesson, write the user-visible success metric first, then the failure mode you fear most. Design the smallest mechanism that protects that metric under partial failure. Prefer explicit timeouts, idempotency, and ownership over adding more infrastructure boxes.
In interviews or design reviews, narrate assumptions, request paths, and trade-offs out loud. A correct-enough design with clear failure handling beats a buzzword diagram without numbers. Revisit the worked example and restate it for a different domain to prove you own the ideas, not the template wording.
Extra teaching notes
When you apply this lesson, write the user-visible success metric first, then the failure mode you fear most. Design the smallest mechanism that protects that metric under partial failure. Prefer explicit timeouts, idempotency, and ownership over adding more infrastructure boxes.
In interviews or design reviews, narrate assumptions, request paths, and trade-offs out loud. A correct-enough design with clear failure handling beats a buzzword diagram without numbers. Revisit the worked example and restate it for a different domain to prove you own the ideas, not the template wording.
Extra teaching notes
When you apply this lesson, write the user-visible success metric first, then the failure mode you fear most. Design the smallest mechanism that protects that metric under partial failure. Prefer explicit timeouts, idempotency, and ownership over adding more infrastructure boxes.
In interviews or design reviews, narrate assumptions, request paths, and trade-offs out loud. A correct-enough design with clear failure handling beats a buzzword diagram without numbers. Revisit the worked example and restate it for a different domain to prove you own the ideas, not the template wording.
Interview and production field guide for this topic
Use this section as deliberate practice, not filler. Rewrite the worked example for a second domain you know well—fintech, education, logistics, or media. Keep the same skeleton: requirements, estimates, high-level diagram, request path, data model, scale lever, failure modes, and trade-offs. If you cannot fill every section without copying buzzwords, you do not yet own the design.
Numbers to force yourself to state
Always speak order-of-magnitude figures: peak QPS, storage growth per day, fan-out factor, connection counts, or queue depth. Wrong numbers that are explicit beat silent hand-waving. Correct the numbers when the interviewer or teammate challenges them; that is collaboration, not failure.
Failure minute
Set a timer for sixty seconds and list only failures: timeouts, duplicates, hot keys, dependency outages, bad deploys, and data corruption paths. For each, name detection and first mitigation. Designs that only describe the happy path are incomplete for production and weak in interviews.
Ownership and operability
Name the dashboard, the alert, the runbook section, and the team that pages. If any are blank, the system will train you during an incident. Prefer progressive delivery: canaries, flags, and rollback notes written before the change lands.
Consistency and retries
State whether the design assumes at-least-once delivery, whether handlers are idempotent, and where unique constraints live. Retries without idempotency are how double charges, double messages, and duplicate fan-out jobs appear. Timeouts without bounds are how thread pools die.
What good looks like in a review
A strong design review or interview answer clarifies scope, makes assumptions audible, draws a minimal path, deepens one or two bottlenecks, and closes with trade-offs and evolution. Use that bar on design-instagram round 0 every time you revisit it.
FAQ from first-time learners
Q: SQL or NoSQL for posts?
A: Either works for MVP; justify lookup by postId and by userId recent posts.
Q: Do I need ML ranking?
A: Mention as evolution; do not block MVP chronology.
Q: Kafka?
A: Useful for fan-out jobs and async pipelines—explain the consumer responsibility.
Track: Distributed Systems
Previous: Design Dropbox — File Sync and Storage
Next: Design Search Autocomplete — Typeahead Suggestions
By Shubham Jain