- Functional requirements say what the system does (post a photo, see a feed). Non-functional requirements say how well it does it (scale, latency, availability, durability, consistency, security, cost).
- Prioritise ruthlessly: for Instagram, core = post, follow, feed, like/comment, profiles; extended = Stories, search, DMs, notifications, Explore; out of scope = ads, shopping, live, payments.
- Working assumptions for this guide: 2B MAU, 500M DAU, ~100M posts/day, feed p99 < ~300 ms server-side, 99.99% availability (≈ 52 min downtime/year), media durability of 11 nines, read-heavy (~100:1 content views to uploads).
- Consistency is chosen per feature: strong for auth and username uniqueness, ordered for DMs, eventual for feeds, likes and follower counts.
- Non-functional requirements become measurable SLIs and SLOs, and every requirement should map to a concrete design decision and component. Change a requirement (E2EE DMs, chronological feed) and the design changes.
1. The problem: why requirements come first
"Design Instagram" could mean a weekend photo-sharing app for 1,000 people or a planet-scale platform for two billion. Those two systems share a name and almost nothing else: the first runs on one server with one database; the second needs CDNs, sharded databases, event streams, caches, ML pipelines and multiple data centres. Every architectural decision depends on the requirements. Without them, you can't tell whether a design is good — only whether it's elaborate.
Requirements also protect you from the two classic failure modes:
- Under-engineering — a single PostgreSQL instance serving 300,000 feed reads per second. It will fall over.
- Over-engineering — globally replicated consensus databases for like counts that nobody needs to be exact. It works, but it is slow, costly and complex for no benefit.
In an interview the first five minutes are spent here (see How to Approach). In real companies this phase is a design document's "Goals / Non-goals" section, and it is where most expensive mistakes are either made or avoided.
2. Functional vs non-functional requirements
| Functional | Non-functional (a.k.a. quality attributes, "-ilities") | |
|---|---|---|
| Describes | Behaviour: inputs, outputs, features | Qualities and constraints of that behaviour |
| Phrased as | "A user can…", user stories | Measurable targets: "p99 < 300 ms", "99.99% monthly" |
| Drives | Which services, APIs and data entities exist | Replication, caching, sharding, consistency model, regions |
| Failure looks like | Feature missing or wrong | Feature exists but is slow, down, loses data, leaks data, or costs too much |
| Instagram example | "Users can like a post" | "Like is acknowledged in < 100 ms; count may lag by a few seconds" |
A useful trick: functional requirements are about one user's experience; non-functional requirements are about all users at once — at peak, during failures, over years.
3. Functional requirements for Instagram
3.1 The feature list with priorities
We classify each feature as Core (must design end-to-end), Extended (show where it plugs in; design in depth only if asked) or Out of scope (explicitly excluded — saying so is a sign of judgement, not laziness).
| Feature | What exactly the user can do | Priority | Owning component in the diagram |
|---|---|---|---|
| Post photo / video / carousel | Upload 1–10 media items (photos or videos up to a size/length limit) with caption, location and tags; the post appears on the profile and in followers' feeds | Core | Upload Service, Object Storage, Media Processing Workers, Post metadata (Cassandra) |
| Home feed | Scroll an infinite, ranked list of recent posts from followed accounts; pull-to-refresh shows new posts | Core | News Feed Service, Feed Cache (Redis), Fan-out Workers, CDN |
| Follow / unfollow | Follow public accounts instantly; request to follow private accounts; see follower/following lists and counts | Core | Follow/Graph Service, Social Graph store |
| Like & comment | Like/unlike (idempotent), comment, reply, see counts and latest comments | Core | Like & Comment Service, Cassandra, counters in Redis |
| Profiles | View a user's bio, counts and grid of posts; edit own profile; private/public setting | Core | User/Auth Service, User DB (PostgreSQL), Post metadata |
| Sign-up / login | Create an account with a unique username; log in; sessions across devices | Core (often assumed) | User/Auth Service, API Gateway, User DB |
| Stories | Post photo/video that disappears after 24 h; see a tray of followed accounts' stories; viewers list | Extended | Stories Service (24h TTL), Object Storage, Feed Cache |
| Search | Find users, hashtags and places by prefix (typeahead) | Extended | Search Service, Search Indexer, Elasticsearch |
| Direct messages | 1:1 and group chats, real-time delivery, read receipts, media sharing | Extended | Direct Messaging (WebSocket), Messages Store |
| Notifications | Push and in-app alerts for likes, comments, follows, mentions, DMs | Extended | Notification Service, Push Providers (APNs/FCM) |
| Explore | Personalised grid of posts from accounts you don't follow | Extended | Analytics & ML Training, ranking service, Feed Cache |
| Reels | Short-form vertical video feed | Extended (shares the video pipeline) | Upload, Media Processing, ML ranking, CDN |
| Ads, shopping, payments, live video, creator monetisation, content moderation tooling, account recovery flows | — | Out of scope | — (mention that they exist) |
3.2 Write them as user stories with acceptance criteria
Turning features into precise statements exposes hidden requirements:
As a user, I can publish a post with 1–10 photos/videos and a caption.
- Upload succeeds on flaky mobile networks (resumable, retry-safe).
- The post shows on my profile immediately after I publish it (read-your-writes).
- Followers see it in their feeds within ~seconds to a minute.
- Videos may show "processing" for a short time; photos appear immediately.
As a user, I can open my home feed and scroll.
- First page renders quickly; next pages load before I reach them (prefetch).
- Ranked by relevance, mostly recent posts from accounts I follow.
- Never shows posts from accounts that blocked me or that I can't access.
As a user, I can like a post.
- Tapping like twice does not create two likes (idempotent).
- The heart turns red instantly; the count may lag slightly.
Each acceptance criterion quietly introduces a non-functional requirement (resumability, read-your-writes, freshness, privacy, idempotency) — exactly the material for the next section.
3.3 Functional requirements that people forget
- Deletion and editing — deleting a post must remove it from feeds, caches, search and (eventually) storage and the CDN.
- Privacy controls — private accounts, blocking, muting, "close friends" Stories audiences.
- Pagination — every list (feed, comments, followers) is unbounded and must be paged.
- Multi-device — the same account on a phone, a tablet and the web; state must sync.
- Internationalisation — Unicode usernames and captions, right-to-left scripts, local time zones.
4. Non-functional requirements
These are the numbers that shape the architecture. In an interview, you propose them and the interviewer adjusts them. Below are the working assumptions used throughout this guide — they are assumptions for design purposes, not official Instagram statistics.
4.1 Scale assumptions
| Metric | Assumption | Average rate | Implication |
|---|---|---|---|
| Monthly active users (MAU) | 2 billion | — | User table ~2B rows → must be sharded |
| Daily active users (DAU) | 500 million | — | Hot data set ≈ DAU's data; caches sized for DAU |
| New posts | 100M/day | ~1.2K/s (peak ~3.5K/s) | Media ingestion hundreds of TB/day |
| Stories | 200M/day | ~2.3K/s | TTL storage; huge view traffic |
| Feed page loads | 10B/day (20 per DAU) | ~116K/s (peak ~350K/s) | Read path must be served from memory |
| Likes | 5B/day | ~58K/s (peak ~175K/s) | High-write store + counters |
| Comments | 500M/day | ~5.8K/s | Sharded by post |
| Media views | ~100 images + ~30 videos per DAU/day | ~tens of PB/day egress | CDN mandatory |
| Average follows per user | ~200 (celebrities: 100M+ followers) | — | Fan-out ~200× per post; celebrity hot spots |
How these numbers are derived and what they imply for storage, bandwidth and servers is worked through in Back-of-the-Envelope Estimation.
4.2 Availability: 99.99% and what it really means
Availability is the fraction of time (or of requests) for which the system works correctly. It is usually expressed in "nines":
| Target | Downtime per year | per month | per day |
|---|---|---|---|
| 99.9% ("three nines") | ≈ 8.8 hours | ≈ 43.8 minutes | ≈ 86 seconds |
| 99.95% | ≈ 4.4 hours | ≈ 21.9 minutes | ≈ 43 seconds |
| 99.99% ("four nines") | ≈ 52.6 minutes | ≈ 4.4 minutes | ≈ 8.6 seconds |
| 99.999% ("five nines") | ≈ 5.3 minutes | ≈ 26 seconds | ≈ 0.9 seconds |
For Instagram we target 99.99% for the core read path (feed, profiles, media) and for uploads. Four minutes per month is far less than the time it takes a human to be paged, log in and diagnose a problem — so four nines cannot be achieved by humans fixing things. It requires automatic failover, redundancy in every layer, gradual rollouts with automatic rollback, and graceful degradation. Extended features such as search or Explore can reasonably target 99.9%: if search is briefly down, the app is still usable.
Two practical refinements:
- Request-based availability is more useful than time-based at this scale:
availability = successful requests / valid requests. A 1% error rate for an hour is a partial outage, not "up" or "down". - Graceful degradation counts. If ranking is down and we serve a chronological feed, the request succeeded — the user saw a feed. Define "success" carefully.
The maths of how component availabilities combine (series vs parallel) is in Core Principles.
4.3 Latency targets
Latency is the time from request to response. We specify it with percentiles, not averages: "p99 = 300 ms" means 99% of requests finish within 300 ms. Averages hide the slow tail that real users feel — a user who loads 20 feed pages per day will hit the p95 experience about once a day. (Percentiles are explained in depth in Core Principles.)
| Operation | Target (server-side unless noted) | Why this number |
|---|---|---|
| Home feed, first page | p50 < 100 ms, p99 < 300 ms | Opening the app must feel instant; it's the most frequent action |
| First image visible (end-to-end, on device) | < 1 s on 4G for p90 | Perceived speed; needs CDN + small thumbnails + prefetch |
| Like / comment acknowledgement | p99 < 200 ms | UI is optimistic (heart turns red immediately), server can be slightly slower |
| Upload acknowledged (photo) | p99 < 2 s after bytes arrive | Heavy work (resize, transcode) is async |
| Post visible in followers' feeds | p99 < ~1 minute (typically seconds) | Freshness requirement; drives fan-out design |
| Search typeahead | p99 < 150 ms | Must keep up with typing |
| DM delivery to an online recipient | p99 < 500 ms | Chat must feel real-time → persistent WebSockets |
| Push notification delivered | Seconds (best effort) | Depends on APNs/FCM; not under our full control |
4.4 Durability of media and data
Durability is the probability that data, once acknowledged as stored, is never lost. It is different from availability: a photo can be temporarily unavailable (a region is down) but must never be permanently lost.
- Media: target object-storage-class durability (S3 is designed for 99.999999999% — "11 nines" — annual object durability). Achieved by replicating or erasure-coding each object across multiple disks, racks and availability zones, plus cross-region copies for disaster recovery. See Object Storage.
- Acknowledged writes: once the app says "posted", the post must survive any single machine or zone failure. That means the metadata write is replicated (e.g. Cassandra with replication factor 3 and a quorum write) before success is returned — an RPO (recovery point objective: how much data you can lose) of zero for posts.
- Derived data is re-buildable: timelines in Redis, search indexes and counters can be regenerated from the source of truth, so they need availability more than durability.
- Deletes must also be durable: when a user deletes content, it must not resurface from a replica or backup restore.
4.5 Consistency expectations per feature
Consistency here means: after a write, what can readers see? Strong consistency (everyone sees the latest write immediately) costs latency and availability, so we pay for it only where users would notice or be harmed. Full theory in CAP, PACELC & Consistency Models.
| Feature | Required consistency | Reason |
|---|---|---|
| Username uniqueness | Strong (linearizable) | Two people must never both get @sunset; a duplicate is a correctness bug |
| Login, password change, session revocation | Strong | A changed password or revoked session must take effect everywhere immediately — security |
| Privacy settings, blocks | Strong-ish; fail closed | A blocked user seeing your post, even briefly, is a privacy incident |
| Direct messages | Ordered per conversation, no loss, no duplicates shown | Messages out of order change meaning |
| My own post on my profile | Read-your-writes | "I posted and it's not there" looks like a bug |
| Home feed | Eventual (seconds) | Nobody can tell if a friend's post arrived 3 s late |
| Like counts, view counts, follower counts | Eventual; approximate OK | "1.2M likes" doesn't need to be exact; huge write rates |
| Stories | Eventual; expiry within minutes of 24 h | Small staleness is invisible |
| Search index | Eventual (seconds–minutes) | Indexed asynchronously from Kafka |
4.6 Read:write ratio
Instagram is read-heavy, but the ratio depends on what you count:
- Content views vs content creation: each post is created once and viewed hundreds of times → ~100:1 or more. This is the ratio that justifies pre-computed feeds, caches and CDNs.
- Bytes out vs bytes in: media egress (tens of PB/day) vs uploads (hundreds of TB/day) → also ~100:1.
- API requests: likes are writes and very frequent, so at the API level the ratio is lower (perhaps ~3–5:1). That's why the like path is designed as a write-optimised path (append-only store, sharded counters) even inside a read-heavy product.
Saying "read-heavy, ~100:1, so I'll optimise reads — but likes are a high-volume write path that needs special handling" is a strong, nuanced interview statement.
4.7 Security & privacy
- Authentication & authorization on every request at the API Gateway; tokens with expiry; per-object access checks (private accounts, blocks). See Authentication.
- Encryption in transit (TLS everywhere, including service-to-service) and at rest (disk/object encryption, managed keys).
- Media access control: signed, expiring CDN URLs so private photos can't be hot-linked forever (see CDN).
- Abuse prevention: rate limiting, spam and bot detection, content moderation in the media pipeline.
- Regulation: data deletion and export (e.g. GDPR "right to erasure"), data residency where required, minors' protections, audit logs.
Details in Security & Privacy.
4.8 Cost
At this scale, cost is a first-class requirement. A design that is 20% cheaper per user saves enormous amounts annually. The big cost drivers are media storage (PBs per year, growing forever), egress bandwidth (CDN), RAM for caches, and compute for transcoding and ML. Cost-shaped decisions include storage tiering (move old, rarely-viewed media to cheaper cold storage), efficient codecs (WebP/AVIF images, modern video codecs), not fanning out to inactive users, and right-sizing caches with the 80/20 rule.
4.9 Other quality attributes
| Attribute | Instagram expectation |
|---|---|
| Scalability | Handle 2–3× daily peaks, viral spikes (a celebrity post) and multi-year growth without redesign — horizontal scaling everywhere |
| Fault tolerance | Survive loss of any server, any availability zone, ideally any region |
| Observability | Metrics, logs and traces for every service; SLO dashboards and alerts (Observability) |
| Maintainability | Hundreds of engineers deploy many times per day safely; independent services (Microservices) |
| Mobile constraints | Flaky networks, limited battery and data; resumable uploads; offline-tolerant UI (Clients) |
5. Making requirements measurable: SLIs, SLOs and SLAs
"Fast" and "reliable" are not testable. Site Reliability Engineering (SRE) practice turns non-functional requirements into three precise terms:
📏 SLI — Service Level Indicator
A measurement. E.g. "the fraction of feed requests that return 2xx in under 300 ms, measured at the load balancer".
🎯 SLO — Service Level Objective
A target for an SLI over a window. E.g. "99.9% of feed requests in a rolling 28 days are fast and successful".
📜 SLA — Service Level Agreement
A contract with consequences (refunds) if missed. Consumer apps like Instagram don't have SLAs with users; cloud providers and B2B APIs do. SLAs are set looser than internal SLOs.
💰 Error budget
1 − SLO. The amount of unreliability you're allowed. 99.9% → 0.1% of requests may fail. Spend it on deploys and experiments; freeze risky launches when it's exhausted.
5.1 Example SLOs for Instagram
| User journey | SLI (good events / valid events) | SLO (28-day window) |
|---|---|---|
| Open feed | Feed responses with 2xx and latency < 300 ms | 99.9% (availability-only SLI: 99.99%) |
| Publish post | Post creations acknowledged successfully | 99.99% |
| Post propagation | Posts present in 99% of followers' timelines within 60 s | 99% |
| Media delivery | CDN media requests 2xx with time-to-first-byte < 200 ms | 99.9% |
| Send DM | Messages delivered to online recipients within 1 s | 99.9% |
| Durability | Acknowledged media objects readable later | 11 nines (annual) |
6. From requirement to design decision to component
This is the most important table in the lesson. Every box in the Instagram diagram exists because of a requirement — if you can't say which one, the box probably shouldn't be there.
| Requirement | Design decision | Component in the diagram |
|---|---|---|
| Post photos/videos up to hundreds of MB on mobile networks | Direct-to-storage uploads via pre-signed URLs; resumable chunks | Upload Service + Object Storage (Media Upload) |
| Media must never be lost (11 nines) | Erasure-coded/replicated blob store across zones + cross-region copy | Object Storage (Object Storage) |
| Media must load fast worldwide; tens of PB/day egress | Pull CDN with versioned, signed URLs | CDN (CDN) |
| Multiple device sizes, video on slow networks | Async resize/transcode into renditions + adaptive bitrate | Media Processing Workers (Media Processing) |
| Feed p99 < 300 ms at ~350K req/s peak | Pre-computed timelines in memory (fan-out on write) | Feed Fan-out Workers + Feed Cache/Redis (News Feed) |
| Celebrities with 100M+ followers | Hybrid fan-out: pull celebrity posts at read time | News Feed Service (News Feed) |
| Ranked feed and Explore | Event logging + offline training + online scoring | Analytics & ML Training (Analytics & ML) |
| ~58K likes/s, eventual counts OK | Append-only write-optimised store + sharded/cached counters | Like & Comment Service, Cassandra, Redis (Likes & Comments) |
| 2B users, unique usernames (strong) | Relational DB with unique constraint, sharded by user_id, with replicas | User DB / PostgreSQL (Databases, Sharding) |
| Billions of posts, write-heavy, "latest posts by user" | Wide-column store partitioned by user_id, clustered by time-ordered post_id | Post metadata / Cassandra (ID Generation) |
| Who follows whom, both directions, fast | Adjacency lists stored in both directions | Follow/Graph Service + Social Graph store (Social Graph) |
| Stories disappear after 24 h | TTL on metadata and timeline entries; lifecycle rules for media | Stories Service (Stories) |
| Typeahead search p99 < 150 ms | Inverted index + prefix index, updated asynchronously | Search Service, Search Indexer, Elasticsearch (Search) |
| Real-time DMs, ordered per conversation | Persistent WebSocket connections; per-conversation sequence numbers | Direct Messaging + Messages Store (Direct Messaging) |
| Users notified of likes/comments/follows | Event-driven notification pipeline with batching and dedupe | Notification Service → APNs/FCM (Notifications) |
| Decoupled side effects; absorb spikes | Publish domain events, process asynchronously | Kafka event bus (Message Queues) |
| 99.99% availability | No SPOFs: redundant LBs, stateless services in many zones, replicated stores, automatic failover | Load Balancer, all stores' replicas (Core Principles, Replication) |
| Global users, regional disasters | Multi-region deployment, geo-routing | DNS + regions (DNS, Multi-Region) |
| Security, abuse prevention | Central auth, TLS termination, rate limits | API Gateway (API Gateway, Rate Limiting) |
REQUIREMENT DECISION COMPONENT ───────────── ───────── ───────── "feed p99 < 300 ms" ───────> precompute timelines ────────> Fan-out workers ─> Redis "~100:1 read-heavy" ───────> cache + replicas + CDN ──────> Redis, read replicas, CDN "never lose a photo" ───────> replicate across zones ──────> Object storage (S3) "unique usernames" ───────> single-leader + UNIQUE ──────> PostgreSQL (sharded) "counts can lag" ───────> async, eventual counters ────> Kafka ─> Redis counters
7. Clarifying questions to ask the interviewer
Below are the questions worth asking for "Design Instagram", with typical interviewer answers and what you do with them. You won't ask all of them — pick the 6–8 that most change the design, and propose an answer in the same breath ("I'll assume X — OK?").
| # | Question | Example answer | Design consequence |
|---|---|---|---|
| 1 | Which features are in scope? I'd propose upload, follow, feed, like/comment as core. | "Yes, plus Stories if time allows." | Deep dives on feed and upload; Stories as TTL extension |
| 2 | How many users? DAU/MAU? Global? | "2B MAU, 500M DAU, worldwide." | Sharding, CDN, multi-region |
| 3 | Photos only, or videos too? Size/length limits? | "Both; videos up to a few minutes." | Transcoding pipeline; adaptive streaming; storage ×several |
| 4 | Is the feed ranked or chronological? | "Ranked, but mostly recent posts from people you follow." | ML ranking stage; candidate generation + scoring |
| 5 | How fresh must the feed be? | "A new post should show within a minute." | Async fan-out acceptable; no synchronous fan-out |
| 6 | Are follows one-directional? Any accounts with huge follower counts? | "One-way; top accounts have hundreds of millions." | Hybrid push/pull fan-out |
| 7 | Latency target for the feed? | "Feels instant — let's say p99 under 300 ms server-side." | Timelines in memory; aggressive caching |
| 8 | Availability expectations? Is brief staleness OK for likes and feeds? | "Highly available; staleness of seconds is fine." | AP-leaning stores, async counters (CAP) |
| 9 | Private accounts and blocking? | "Yes, both." | Authorization check on every read path; filter at fan-out and at read |
| 10 | Can users edit/delete posts? Any legal deletion requirements? | "Delete yes; edit caption only." | Deletion propagation to caches, search, CDN; tombstones |
| 11 | Do we need DMs? Encrypted end-to-end? | "Out of scope for now." | Show the box; skip design |
| 12 | Read:write expectations? | "Heavily read-dominated." | Optimise reads (caches, replicas, CDN) |
| 13 | Any cost or team constraints? Build on a cloud provider? | "Assume a large cloud; cost matters but isn't the main focus." | Managed services (S3, managed Kafka) are acceptable |
| 14 | Analytics / notifications required? | "Notifications for likes and follows, yes." | Event-driven notification pipeline |
8. How requirements change the design
The best way to understand requirements is to see what happens when one changes. Interviewers love this as a follow-up ("what if…?").
| If the requirement becomes… | …the design changes like this |
|---|---|
| DMs must be end-to-end encrypted (E2EE) | The server can no longer read message content: no server-side search over messages, no server-side spam/content scanning of text, no server-rendered link previews. Clients manage keys (e.g. Signal-protocol style key exchange, per-device keys); multi-device sync and history restore become hard (encrypted backups); moderation shifts to metadata and user reports. The Messages Store holds ciphertext only. |
| The feed must be strictly chronological | The ML ranking stage disappears; the timeline is a simple time-sorted merge. Fan-out still helps, but pull-on-read (merge the latest posts of each followee, k-way merge by timestamp) becomes more attractive because no scoring is needed. "Exactly in order" also demands time-ordered IDs (ID Generation) and consistent clocks. |
| Like counts must be exact and real-time | Async counters aren't enough; you need atomic increments on a strongly consistent counter — a hot-key problem for viral posts (millions of likes/hour on one row). Expect sharded counters with synchronous aggregation, higher latency, and lower availability during partitions. |
| Video-first (like Reels/TikTok) | Storage and egress grow ~10×; transcoding compute dominates; adaptive bitrate streaming; the feed becomes a recommendation feed (Explore-like) driven mostly by ML rather than the follow graph. |
| Only one country, 10M users | One region; a single primary PostgreSQL with replicas may handle all metadata; simple fan-out; maybe a commercial CDN. Far fewer moving parts — and that's the right answer for that requirement. |
| Data residency (EU data must stay in the EU) | Region-pinned storage per user; routing users to their home region; cross-region features (a German user following a US user) need careful replication of only allowed data. |
| Posts must appear in followers' feeds within 1 second | Fan-out must be fast and prioritised; celebrity pulls at read time; possibly push notifications over persistent connections. Much more infrastructure for marginal user value — worth questioning the requirement. |
| 99.999% availability | Multi-region active-active for reads and writes, automated regional failover, conflict resolution for concurrent writes, extremely conservative deploys. Cost and complexity increase sharply for each additional nine. |
| Stories must vanish at exactly 24:00:00 | Read-time filtering by expires_at (cheap, exact) instead of relying on background TTL deletion (lazy, approximate). CDN URLs must expire too. |
9. How Instagram uses requirements to shape its design
Reading the Instagram diagram through the lens of requirements:
- The API path and the media path are separate because the latency and bandwidth requirements of the two are completely different — JSON responses are small and personalised (served by services), media is huge and shared (served by the CDN).
- Kafka sits in the middle because many requirements are "eventually, within seconds" (fan-out, search indexing, notifications, analytics) rather than "before the response". Doing them asynchronously keeps the upload latency target and isolates failures.
- Different stores for different consistency needs: PostgreSQL where uniqueness and transactions matter (users), Cassandra where write throughput and availability matter (posts, likes), Redis where latency matters (timelines, counters).
- Stateless services exist because of the availability and scalability requirements: any instance can die or be added without losing data.
A worked requirements summary (what you'd leave on the whiteboard)
INSTAGRAM — REQUIREMENTS (agreed with interviewer)
Functional (core): post photo/video/carousel · home feed (ranked) · follow/unfollow
like/comment · profiles · auth
Functional (extended): stories (24h) · search · DMs · notifications · explore
Out of scope: ads · shopping · payments · live
Scale: 2B MAU · 500M DAU · 100M posts/day · 10B feed loads/day · 5B likes/day
Latency: feed p99 < 300 ms (server) · like ack p99 < 200 ms · post visible to followers < 1 min
Availability: 99.99% feed/upload/media · 99.9% search/explore
Durability: no acknowledged post/media ever lost (11 nines media)
Consistency: strong → usernames, auth, privacy · ordered → DMs
read-your-writes → own posts · eventual → feed, counts, search
Read:write: ~100:1 content views : uploads (likes = heavy write path)
Security: authN/Z on every request, TLS, signed media URLs, privacy, deletion
Cost: storage tiering, efficient codecs, skip inactive users in fan-out
10. Trade-offs & common pitfalls
✅ Spending time on requirements
- Prevents designing the wrong thing
- Gives you numbers to justify every component
- Lets you choose consistency per feature instead of one-size-fits-all
- Creates a checklist to verify the final design against
- Signals product sense and seniority
⚠️ Costs and risks
- Takes time from design — over 7–8 minutes hurts
- Too many open questions sound indecisive
- Over-specifying (exact numbers to 3 significant figures) wastes effort
- Rigid requirements can hide better options — sometimes the right move is to negotiate them
Common pitfalls
- Skipping non-functional requirements. Listing features only, then having no basis for choosing caches, replicas or consistency models.
- "Highly available and strongly consistent everywhere." During a network partition you can't have both (CAP); pick per feature.
- Averages instead of percentiles. "Average latency 100 ms" says nothing about the 1% of users waiting 3 seconds.
- Confusing availability with durability. A system can be up and still have lost data, or down with all data safe.
- Forgetting deletes and privacy. Blocked users, private accounts and legal deletion touch every read path and every cache.
- Scope creep. Trying to cover DMs, Reels, Explore and ads in 45 minutes. Say "out of scope" explicitly.
- Treating assumptions as facts. Say "assume 500M DAU", not "Instagram has exactly 500M DAU".
- Setting a 100% target. Leaves no error budget and is physically impossible.
11. Real-world technologies
| Tool / practice | What it's for | When to use it |
|---|---|---|
| Design docs / RFCs (Goals, Non-goals, Requirements sections) | Agreeing requirements before building | Every non-trivial project |
| User stories + acceptance criteria (Jira, Linear, etc.) | Precise functional requirements | Feature planning |
| MoSCoW prioritisation (Must/Should/Could/Won't) | Core vs extended vs out-of-scope | Scoping a release or an interview answer |
| Prometheus + Grafana; Datadog; Google Cloud Monitoring SLOs | Measuring SLIs, SLO dashboards, burn-rate alerts | Any production service with an SLO |
| OpenSLO / Sloth (SLO-as-code) | Declaring SLOs in version-controlled config | Many services, consistent SLO definitions |
| Real-user monitoring (RUM), mobile performance SDKs | Client-side latency SLIs (first image visible) | User-facing apps where network dominates |
| Load-testing tools (k6, Locust, Gatling, JMeter) | Verifying scale and latency requirements before launch | Pre-launch and capacity planning |
| Chaos engineering (Chaos Monkey, Gremlin, LitmusChaos) | Verifying availability/fault-tolerance requirements | Systems targeting 99.99%+ |
12. Interview corner
What's the difference between functional and non-functional requirements? Give Instagram examples.
Functional requirements describe behaviour — what a user can do: "upload a photo with a caption", "see a feed of followed accounts", "like a post". Non-functional requirements describe qualities of that behaviour across all users: "feed p99 under 300 ms at 350K requests/s", "99.99% availability", "no acknowledged upload is ever lost", "like counts may be eventually consistent". Functional requirements decide which services and entities exist; non-functional ones decide how they are built — caching, replication, sharding, consistency model, regions.
What does 99.99% availability mean, and how would you achieve it for Instagram's feed?
At most ~52.6 minutes of downtime per year, ~4.4 minutes per month, or 0.01% of requests failing. That's faster than any human can respond, so it requires automation: no single points of failure (redundant load balancers, stateless services across ≥3 availability zones, replicated Redis and databases with automatic failover), health-checked load balancing, gradual deploys with automatic rollback, timeouts and circuit breakers, and graceful degradation — e.g. if ranking fails, serve a chronological timeline from the cache; if the cache fails, serve a smaller feed built from the post store.
Which Instagram features need strong consistency and which can be eventual? Why?
Strong: username uniqueness (duplicates are a correctness bug), authentication and session revocation (security), privacy settings and blocks (privacy harm). Ordered: DMs within a conversation. Read-your-writes: a user's own posts and profile edits. Eventual: home feed, like/view/follower counts, search index, Stories tray — a few seconds of staleness is invisible and buys low latency and high availability at huge write rates.
Why specify latency as p99 rather than average?
Averages hide the tail. If 99% of requests take 50 ms and 1% take 5 s, the average is ~100 ms — it looks fine but one request in a hundred is terrible. Heavy users make many requests per day, so most of them experience the tail daily. Also, a page that calls many backends is slowed by the slowest one, so tail latency of components becomes typical latency of the page. p99 (or p99.9) targets force you to control the tail.
Explain SLI, SLO, SLA and error budget with an Instagram example.
SLI: the measured fraction of feed requests that succeed in under 300 ms. SLO: the target, e.g. 99.9% over 28 days. SLA: an external contract with penalties — Instagram doesn't have one with consumers, but a cloud provider has one with Instagram, and it's looser than internal SLOs. Error budget: 1 − SLO = 0.1% — with ~280B feed requests in 28 days, about 280M may be bad. Teams spend the budget on risk (deploys, experiments); if it's exhausted, they pause launches and fix reliability.
The interviewer says DMs must now be end-to-end encrypted. What changes?
The server only stores and forwards ciphertext. Keys live on devices (per-device identity keys, a Signal-style protocol for session setup), so: multi-device requires encrypting each message for every device of every participant (fan-out per device); message history on a new device needs encrypted backups or device-to-device transfer; server-side features that read content — search over messages, link previews, spam/abuse classifiers on text — move to the client or rely on metadata and user reports. Storage, ordering and delivery mechanics stay similar.
How would you prioritise features when the interviewer says "Design Instagram" with no other guidance?
Propose: core = posting media, following, home feed, like/comment, profiles — the loop that makes Instagram work (create → distribute → consume → engage). Extended = Stories, search, DMs, notifications, Explore — I'll show where they plug in. Out of scope = ads, shopping, payments, live video. Then confirm with the interviewer and ask which part they'd like to dig into. This focuses time on the feed and media pipeline, where the hard scaling problems are.
Is Instagram read-heavy or write-heavy? Be precise.
Read-heavy for content: each post is created once and viewed hundreds of times (~100:1 or more), and media bytes out exceed bytes in by a similar factor — so we optimise reads with timelines in Redis, caches and a CDN. But some paths are write-heavy: likes (~58K/s average under our assumptions), view counters, and the fan-out of each post to hundreds of follower timelines (~20B timeline inserts/day). Those get write-optimised designs: append-only stores, batching, sharded counters.
13. Check your understanding
Classify: (a) "users can delete comments", (b) "comment deletion propagates within 5 seconds", (c) "comments are stored encrypted at rest", (d) "users can reply to a comment".
(a) and (d) are functional (behaviours). (b) is non-functional (a latency/consistency target). (c) is non-functional (security).
Numeric: a service has an SLO of 99.95% availability per 30-day month. How many minutes of downtime is that?
30 days × 1,440 min = 43,200 min. 0.05% of that = 43,200 × 0.0005 = 21.6 minutes per month.
Numeric: with 10B feed loads/day, how many failed requests per day does a 99.99% success SLO allow?
0.01% × 10B = 1 million failed feed requests per day. Large in absolute terms — which is why request-based SLIs are measured as ratios, not counts.
Scenario: your post appears in your followers' feeds 20 seconds after you publish, but on your own profile instantly. Is that a requirements violation?
No. The requirements are read-your-writes for the author's own view (satisfied) and eventual propagation to followers within ~1 minute (satisfied). This is exactly the intended design: the author's write is read from the primary/session, followers get it via asynchronous fan-out.
Why does "username uniqueness" force a different database choice than "like counts"?
Uniqueness requires a linearizable check-and-set: when two people claim the same name simultaneously exactly one must win, which needs a single authority (a leader with a unique constraint, or consensus). Like counts tolerate staleness and approximate values but have a very high write rate, so an AP-leaning, write-optimised store with asynchronous counters fits better.
Which is durability and which is availability: (a) "the photo can't be loaded for 10 minutes during a zone outage", (b) "a disk failure destroyed the only copy of a photo"?
(a) is an availability failure — the data still exists and will come back. (b) is a durability failure — the data is gone forever. Durability is protected with replication/erasure coding across failure domains and backups; availability with redundancy and failover.
The interviewer changes the requirement to "feed must be strictly chronological". Name two components that change.
The ML ranking stage (Analytics & ML / ranking in the News Feed Service) is removed from the read path, and the timeline merge becomes a pure time-ordered merge — which makes pull-on-read (k-way merge of followees' latest posts) more attractive and puts more weight on time-ordered post IDs. Fan-out workers may still be used, but freshness and ordering guarantees become stricter.
Why is "the system must be 100% available" a bad requirement?
It's unachievable (hardware, networks and humans fail), and it leaves an error budget of zero — meaning no deploy, migration or experiment is ever "allowed". Every extra nine costs much more than the last. Choose the lowest target users won't notice and the business can afford.
- Requirements come first: functional = what, non-functional = how well. The second list shapes the architecture far more.
- Prioritise into core / extended / out of scope; for Instagram the core loop is post → fan-out → feed → like/comment.
- Quantify: 500M DAU, ~100M posts/day, feed p99 < 300 ms, 99.99% (~52 min/yr), 11-nines media durability, ~100:1 reads.
- Choose consistency per feature: strong for usernames/auth/privacy, ordered for DMs, read-your-writes for own content, eventual for feeds and counts.
- Make requirements measurable with SLIs, SLOs and error budgets.
- Every component should trace back to a requirement — and changing a requirement (E2EE, chronological feed, exact counts) changes the design.
Related lessons
- How to Approach a System Design Problem — where requirements fit in the 6-step framework
- Back-of-the-Envelope Estimation — turning the scale assumptions into QPS, storage and bandwidth
- Core Principles — availability maths, percentiles, scalability
- CAP, PACELC & Consistency Models — the theory behind per-feature consistency choices
- News Feed — how the latency and freshness requirements are met
- Observability — measuring SLIs and alerting on SLOs
- Security & Privacy — the security and privacy requirements in depth