Learning pathsA
GUIDED PRACTICE

Instagram

Design photo publishing, processing, and a personalized home feed.

Interview scope and guarantees

Upload photos, publish posts, follow accounts, read a feed and like posts. Media can process asynchronously; a visible post must reference a ready media version. Private-account access must be checked independently of cached feed membership.

Capacity worksheet

Assume 20 million uploads/day at 3 MB: 60 TB/day input. Four derivative sizes totaling another 3 MB add 60 TB/day. At 200 million feed opens/day and 20 images/open, there are 4 billion image fetches/day; byte delivery belongs at CDN edges.

Concrete API contract

Contract / pseudocode
POST /media/uploads -> {mediaId,uploadUrl}
POST /posts {mediaIds,caption,visibility} -> {postId}
PUT /posts/{id}/likes/me -> 204
GET /feed?cursor=...

Data model and access paths

Contract / pseudocode
media(id PK,owner_id,state,source_key,derivative_manifest)
posts(id PK,author_id,visibility,created_at,version)
likes(post_id,user_id); UNIQUE(post_id,user_id)
feed_items(user_id,sort_key,post_id)

Evolve a solution and explain each change

Three architecture decisions for Instagram, including the pressure each introduces.
Scroll to inspect the diagram, or open it at full size.

Figure — Three architecture decisions for Instagram, including the pressure each introduces.

Step 1: Publish media

Store an immutable media object and commit an authorized post record. A completed upload alone does not make a post visible.

Step 2: Project feed candidates

Fan out ordinary accounts and merge high-fanout accounts at read time. Fanout delays and duplicate events complicate feed completeness.

Step 3: Deliver media privately

Use renditions and CDN delivery while enforcing current post visibility. Cached thumbnails can leak after permission changes.

Responsibility overview

Connected responsibilities for Instagram. Trace the authoritative and derived paths separately.
Scroll to inspect the diagram, or open it at full size.

Figure — Connected responsibilities for Instagram. Trace the authoritative and derived paths separately.

Worked end-to-end scenario

A creator uploads photo object o31, then publishes post p31 referring to it. If the publish transaction fails, o31 remains an unlisted upload eligible for safe later cleanup. After publication, the outbox updates follower candidates. A follower receives the candidate twice; the post ID makes projection insertion idempotent. Opening the feed rechecks current audience membership before issuing media grants. If the creator becomes private or removes the follower, an old feed candidate and cached thumbnail must not bypass the new policy. Likes and comments are separate records with their own uniqueness and moderation semantics.

Why these access paths matter

Posts are indexed by author and publication order; media keys include immutable rendition identity. Feed candidates are indexed by recipient. A unique user-plus-post like prevents duplicate likes, but a displayed count can be an asynchronous aggregate. Store comment pagination keys explicitly; do not use the current like count as an ordering identity.

Build the baseline first

Instagram: baseline request paths.
Scroll to inspect the diagram, or open it at full size.
  1. Upload → object storage → derivative workers.
  2. Ready media → post transaction → publish event.
  3. Feed candidates → authorization → media grants.

Evolve the design under load

Instagram: additional scaling and recovery paths.
Scroll to inspect the diagram, or open it at full size.
  1. Hybrid feed fanout → inbox and author timelines.
  2. Immutable derivatives → CDN caches.
  3. Like events → counter projection → display.

Defend the hardest decision

Do not publish a post just because an upload URL was issued. Verify the object, scan and transform it, then move media state to ready. Publishing checks ownership and readiness. Like is a set membership operation; using PUT makes repeated requests naturally idempotent. A displayed like count may lag while the user’s own like state comes from the authoritative relation.

Failure and recovery analysis

A user changes an account to private after its posts were fanned out widely. Inbox cleanup alone is too slow to enforce the boundary; filter access before returning metadata and media grants. Cached public media URLs complicate revocation, so the privacy promise and CDN authorization design must agree.

Security and privacy boundary

Validate file types and size, strip sensitive image metadata where appropriate, and prevent unauthorized media reuse.

Interview follow-ups with reasoning

Question: How do you delete a post?

Show answer and explanation

Answer: Tombstone source state, suppress serving, remove projections, then collect media after retention.

Question: How do you handle a viral image?

Show answer and explanation

Answer: Edge cache it while protecting metadata and counter paths.

Question: What happens when derivative generation fails?

Show answer and explanation

Answer: Show processing failure and allow a retry without duplicate posts.

Operate and verify the design

Media processing age, failed derivatives, feed freshness and private-content suppression.

Switch a public account to private during cache hits and verify that new access grants are denied.

A second scenario to test transfer

An ordinary author with 800 followers writes a post; precompute candidates. A celebrity with 30 million followers posts at once; defer that author’s fanout and merge recent posts for active readers. In both cases, the feed candidate is re-authorized before content is shown. One policy handles different fanout economics without weakening privacy.

A feed worker retries an old post event after the author has gone private. What prevents it from reintroducing visible content?

Show answer and explanation

Answer: Write candidates idempotently with the source version and treat them as references only. At read time, check current audience state before returning content or URLs. Propagate removals and reject stale versions to reduce work, but preserve the current authorization check as the visibility boundary.

Compare alternatives

ChoiceBenefitCost
Direct multipart media uploadAPI does not stream huge bytesSession verification and cleanup
Hybrid fanoutHandles author skewRead merge and versioning
Immutable media renditionsCDN reuseLifecycle retention
Visibility recheckProtects stale candidate listsAuthorization read on feed path

A design-changing exercise

The database denies a former follower but the CDN has a cached thumbnail. Is privacy enforced?

Show answer and explanation

Answer: Only if delivery checks authorization or a valid scoped grant. Cache residency does not grant access; define existing grant expiration separately.

Design workshop: publish media separately from feed candidates

Core scope is media posts, follow feed, likes/comments and private visibility. Stories, live video and recommendation training are extensions. Assume feed p95 under 200 ms and uploaded images playable within ten seconds under admitted processing load. Bytes uploaded is not post published; feed candidates are not permission to see media.

Add media(media_id,owner_id,source_key,generation,state), post_media(post_id,media_id,ordinal), follows(follower,author) with reverse author index, comments(id,post_id,author_id,request_key,state), and like_state(post_id,user_id,version,liked). Comments and likes carry stable request identities; current post visibility governs admission and reads. Post creation atomically attaches verified ready media and emits an outbox event. It never exposes a raw unverified upload as the final thumbnail.

Media readiness before post fanout. Creator to Media authority: Create upload session and transfer signed bytes; Transform worker to Media authority: Verify source; produce immutable generation-3 renditions; Creator to Media authority: Publish post linked to ready media generation 3; Media authority to Feed projector: Post/version event after publication commit; Feed projector to Feed projector: Project unique viewer/post candidates for ordinary author; Creator to Media authority: Retry same publish key returns original post
Scroll to inspect the diagram, or open it at full size.

Figure — Media readiness before post fanout.

Transforms validate type and dimensions, strip unsafe metadata under the chosen privacy policy and generate pinned sizes/codecs. Task identity is media/source_version/profile/generation; conditional publication rejects stale workers. Retained renditions use immutable paths. Cleanup needs live post/media references and a deleting state, not only old timestamps.

A hybrid feed pushes ordinary authors and pulls high-fanout authors during read. With one million followers and four posts/day, push produces four million candidate writes/day for one account. If only 5% read five times/day, pull creates 250,000 author merges/day, with different per-operation cost. Use measured thresholds and workload limits. The ranking service merges pushed IDs, pulled timelines and explicitly scoped recommendation candidates, then applies current ACL before hydration.

Like/unlike transitions and private delivery. First Like / false -> true under unique post/user / Count +1 once; Repeated Like / true -> true / No count change; Unlike / true -> false at newer version / Count -1 once; Old Like event after Unlike / Version rejected / No resurrection or second +1; Post made private / Permission version increases / Feed and media access revalidate current policy
Scroll to inspect the diagram, or open it at full size.

Figure — Like/unlike transitions and private delivery.

Counter events contain old/new state and source version. A projector tracks the last applied version per like key, or recomputes on gaps; blindly incrementing for every queue delivery inflates counts. Comments use a durable edit/delete version with current authorization before snippets.

Private media delivery uses an edge/origin authorization boundary. A post going private invalidates controlled grants and caches, but already issued bearer URLs remain usable under their defined lifetime unless the delivery layer checks current permissions. Separate public and private cache policy; changing the application feed alone does not protect a directly accessible object URL. A CDN miss coalesces protected origin reads; the app API does not stream all image bytes.

Exercise: A like version 3 is delayed until after unlike version 4. The counter worker receives 4 then 3. What should it do?

Show answer and explanation

Answer: Resolve the state using source versions; ignore 3 after 4. If a gap prevents a valid delta, recompute that like's current source state and reconcile the aggregate. Final liked state is false, not the last arriving event.

Technical references

Object-store multipart upload.

PostgreSQL transaction isolation and concurrent updates.

10:00Self-guided practice timer
The timer resets when you leave this page. Save your design separately.
Your challenge

A feed worker retries an old post event after the author has gone private. What prevents it from reintroducing visible content?

Your design draft

Clarify assumptions, explain your approach, and test the difficult cases. Save your draft, then compare it with the study notes.

Read study notes

Self-review checklist

Self-guided practice. Automated AI feedback and code execution are not connected.