At a glance
A user opens the app and sees recent posts from people they follow. Writes are relatively rare; reads are constant. The hard part is fan-out cost — especially when one user has millions of followers.
Follow, post, home feed ranked.
Write-time fan-out vs read-time merge.
Push normals · pull celebrities.
Candidates first, rank second.
Hot keys and mega fan-out.
Clarify → HLD → hybrid deep dive.
This is a fan-out cost problem under a skewed follower graph. Compare push vs pull, land on hybrid — push for normal users, pull for celebrities — then deep-dive the celebrity hot key.
Whiteboard order
Draw in this order so push vs pull is visible before you invent ranking ML.
- First — product + NFRs: follow, post, home feed; read-heavy; freshness SLA; celebrity skew called out.
- Second — capacity numbers: DAU, posts/day, avg follows, feed opens/day, celebrity threshold. Circle the fan-out blow-up.
- Third — two fan-out sketches: push on left, pull on right, then hybrid arrow. Entities: posts, follows, timeline.
- Then deep dives: async workers, ranking as a separate stage, hot-key cache, pagination cursors.
Requirements → capacity → push/pull diagram → hybrid. Ranking is a stage after candidates are gathered, not the opening act.
Requirements
Get the product shape before arguing Cassandra vs Redis.
Functional
- Users follow other users (asymmetric — not mutual like Facebook friends).
- Users create posts (text, image, video references).
- Home feed shows posts from followed users, ranked by recency or relevance.
- Optional later: likes, comments, notifications, ads, "people you may know."
Non-functional
- Reads ≫ writes — optimize the feed read path.
- Latency — first page of feed should feel instant (cache-friendly).
- Freshness — eventual consistency OK for many feeds; state your SLA.
- Skew — follower counts follow a power law (celebrities break naive designs).
Lock follow + post + home feed. Reads dominate, first page must feel instant, eventual consistency is fine for a few seconds, and follower counts are power-law — that skew drives the architecture.
Capacity math worked example
Do this arithmetic on the board before arguing Cassandra. Numbers make hybrid inevitable.
- Assumptions: 100M DAU, each opens feed 10×/day, each follows 200 people, 1 post/user/day on average, 0.1% of users are celebrities with ≥1M followers.
- Feed reads: 100M × 10 / 86,400 ≈ ~12k QPS average feed opens. Peak 5–10× → 60–120k QPS. Cache the first page.
- Posts (writes): 100M × 1 / 86,400 ≈ ~1.2k post QPS average. Manageable — the cost is fan-out, not the insert.
- Pure push blow-up: one celebrity with 50M followers → 50M timeline writes per post. Even at 100k writes/sec that's ~8 minutes of fan-out for one trailer drop — and most followers are inactive.
- Normal push: user with 200 followers → 200 timeline writes. Async workers finish in milliseconds. Fine.
- Hybrid savings: push for ~99.9% of users; pull ~100k celebrities at read time into the merge. Celebrity post write cost stays O(1).
This napkin is what turns hybrid from a memorized answer into a derived one. The trade-off is visible in the numbers: pure pull would merge 200 followees' recent posts on every feed open at 12k QPS — doable with good indexes and cache, but precomputed timelines are simply snappier for normal users. Worth anticipating next: inactive followers (skip fan-out until next login) and hot keys when everyone pulls the same celebrity's recent posts.
The celebrity fan-out product — followers × posts — is the one number that makes hybrid inevitable instead of a buzzword.
Push vs pull fan-out
This is the heart of the interview. Draw both, then land on hybrid.
- Fan-out on write (push) — when a post is created, write a pointer into each follower's timeline store. Fast reads; expensive celebrity posts.
- Fan-out on read (pull) — on feed open, fetch recent posts from followed users and merge. Cheap writes; heavier reads.
- Hybrid — push for normal users; pull celebrity posts into the merge at read time.
Tradeoff table in words: Push wins when follower counts are small and feeds must be snappy. Pull wins when graph is sparse or writers are rare celebrities. Real products almost always hybridize.
Why you must draw both before picking: push moves cost to write time, pull moves it to read time. Neither is universally better — the follower distribution decides. Pitch push alone and it collapses the moment one account gets millions of followers. Pitch pull alone and normal users with a few hundred follows pay an unnecessary read cost on every feed open. Land on hybrid with a numeric threshold (e.g. 10k followers) so the rule is testable.
Never pick only push or only pull without naming the celebrity problem. Hybrid, with an explicit follower threshold, is the default answer.
Hybrid design (the default pick)
There's no perfect feed — only the right fan-out for your write and read mix.
Most designs land on hybrid fan-out. Walk it as a sequence so the interviewer can follow.
- Define a follower threshold (e.g. 10k) — above = celebrity.
- Normal user posts → async fan-out on write to all followers' timeline caches.
- Celebrity posts → write to their profile / posts store only; skip mass fan-out.
- On feed read: fetch precomputed timeline + recent posts from followed celebs + merge + rank.
- Return first page; use cursor pagination for the rest.
API sketch — enough to draw three boxes and move on:
POST /posts— body: content, media_refs. Writes to posts store, enqueues fan-out job (skipped for celebrity author_id), returns post_id immediately.POST /follow— body: followee_id. Writes a row to follows; no timeline backfill needed since old posts aren't retro-fanned-out.GET /feed?cursor=— returns ranked page + next cursor (post_id + timestamp), reading from timeline ZSET merged with celebrity pulls.
Post creation should return fast. Fan-out workers consume a queue: look up followers, batch-write timeline rows, handle retries with idempotency keys.
Why async fan-out is non-negotiable: a user with 5k followers cannot wait for 5k synchronous writes on the publish request. Return the post ID immediately; workers churn the timeline store. Trade-off: followers may see the post a second or two later — usually acceptable under your freshness NFR. Worth anticipating: idempotent consumers (retry must not duplicate timeline rows), partial fan-out failure, and what happens when someone unfollows mid-fan-out (orphaned row is fine; next read filters).
Threshold + async workers + timeline table + celebrity pull at read — those four pieces are the whole hybrid design.
Ranking basics
Recency-only is MVP. Production feeds add ranking — engagement signals, affinity, diversity. In interviews, mention ranking as a separate stage after candidate generation.
- Candidate generation — gather ~hundreds of post IDs from timeline + celebrity pulls.
- Ranking — score by recency, affinity, engagement; apply diversity filters.
- Pagination — cursor-based (post_id + timestamp) — stable under new inserts.
- Cache the first page per active user — highest QPS path.
- Rank in app tier or dedicated ranking service — not in a giant DB join.
- Phase two: ML model, ads insertion, "see first" preferences.
Candidates first, rank second — say it in that order. Recency plus a simple score is enough for MVP; don't invent an ML ranker unless asked.
The celebrity problem
Follower graphs are power-law. One superstar-tier account can destroy a naive push design and heat up a single partition on pull.
- Push blow-up — writing tens of millions of timeline rows per celebrity post is slow, costly, and often unnecessary (many followers are inactive).
- Hot keys on pull — everyone reading a celeb's recent posts hits the same author partition / cache key.
- Mitigations — hybrid threshold; dedicated celebrity post cache; replicate hot keys; rate-limit post creation for spam.
- Inactive followers — skip fan-out to dormant users; materialize on next login (lazy fan-out).
Volunteering this early matters because the celebrity problem is the natural deep dive here. Pure push dies on write amplification; pure pull dies when millions of feed opens hammer one author partition. Hybrid plus a dedicated celebrity recent-post cache is the standard recovery. Lazy fan-out to inactive users is a nice-to-have on top — don't spend the whole clock on it.
Volunteer the celebrity problem before being asked. Hybrid plus a hot-key cache on the celebrity's recent posts is the fix.
Caching and scale checklist
Feeds are a caching problem wearing a social-network costume.
- Shard timeline storage by user_id (the reader).
- Async fan-out workers — post creation returns fast; fan-out happens in queue.
- Cache hot timelines / first pages for active users in Redis.
- Cache celebrity recent-post lists separately.
- Media in object storage (S3); feed stores references only.
- Rate-limit post creation; detect spam patterns.
- Idempotent fan-out consumers — retries must not duplicate timeline rows forever.
Failure modes worth naming before asked: Queue lag — if the fan-out queue backs up under a viral spike, normal users see stale feeds for minutes; alert on consumer lag, not just error rate. Partial fan-out — a worker crashes after writing 40k of 200k rows; retry the whole job with an idempotency key (dedup on (post_id, user_id) or an upsert) rather than trusting "it probably finished." Cache stampede — a celebrity's hot-key cache entry expires and thousands of concurrent reads all miss at once and hammer the same author partition; use request coalescing or staggered TTLs. Unfollow mid-fan-out — a user unfollows while their old timeline rows are still being written; treat the orphaned row as harmless and filter it at read time rather than trying to cancel in-flight writes.
Shard by reader, cache the first page, fan out asynchronously, keep media out of band. Design for the skew, not the average.
Interview flow (45 minutes)
Use this as your route so you don't rabbit-hole into ranking ML.
- ~5 min — requirements + NFRs (read-heavy, skew) + rough capacity.
- ~3 min — entities: users, follows, posts, timeline.
- ~5 min — API: create post, follow, get feed (cursor).
- ~12 min — HLD: push vs pull diagram → land on hybrid.
- ~10 min — deep dives: celebrity, caching, ranking stage, pagination.
- ~5 min — wrap-up: MVP sentence + 10× sentence.
Cost and performance levers
Write amplification is a dollar problem, not just a latency one. Every timeline row is a write unit you pay for — 10M followers × 1 post is 10M billed writes on most managed stores, and a handful of celebrity posts a day can dwarf the write cost of every normal user's post combined. The hybrid split isn't only about tail latency; it's the difference between a linear cost curve and one with 50M-write spikes. Layer in lazy fan-out for inactive users: don't write a timeline row for a follower who hasn't opened the app in 30 days — materialize their timeline on next login instead. For a network where a meaningful fraction of accounts are dormant, this alone can cut fan-out write volume substantially without touching the celebrity path at all.
Fan-out decision board
Celebrity problem numbers
1M followers × write fan-out = 1M cache updates per post — too slow/expensive. Exception path: don't precompute; merge celebrity posts at read time from a separate store.
Failure modes to mention
Generic "DB down, add retries" doesn't land in a feed interview. Name the feed-specific ones: fan-out queue backlog during a viral moment (mitigation: autoscale workers, shed load by deprioritizing lazy fan-out first, alert on consumer lag); celebrity read hot key when a trending post's author partition gets hammered (mitigation: dedicated hot-key cache, request coalescing); timeline store partial write from a crashed worker (mitigation: idempotent upserts keyed on (post_id, user_id), not blind retries); and ranking service timeout on the read path (mitigation: degrade to recency-only rather than fail the whole feed request).
Interview Q&A by level
Practice saying these out loud for news feed design. Interviewers grade clarity and judgment more than buzzwords.
Architecture by level
Three progressive sketches — beginner spine, mid optimizations, pro production depth. Use the matching diagram in the interview; say the tradeoff out loud.
Pros: Naming push vs pull with a diagram proves you understand the core cost model. Cons: Pure push explodes on celebrities; pure pull makes every feed open a merge — neither alone is the production answer.
Pros: Hybrid is derived from napkin math (50M fan-out) — push normals, pull celebs keeps write amp and read latency balanced. Cons: Thresholding "who is a celebrity" and hot keys on celeb recent-posts need explicit handling or you recreate the blow-up on read.
Pros: Separate candidate generation from ranking; timeline cache + cold storage match real feed stacks. Cons: Ranking ML and storage topology can swallow the hour — staff depth should pick fan-out math + hot keys, not every subsystem.
Match depth to the bar: define → trade off → operate. Don't dump principal answers in an entry-level screen — but at every level, be able to redraw the push/pull/hybrid sketch from memory without hesitating. Full rubric: Interview bars by level.