Learning pathsPricingA
SOLUTION REVIEW

Review: FB News Feed

Design a feed from posts and a follow graph, with ranking, pagination, deletion, and privacy.

Clarify this prompt before choosing components

Ask the highest-impact questions first, agree on priorities, and record the interviewer’s answers. If a detail is unspecified, state an assumption and explain which decision depends on it. The numbers in this worked lesson are exercise assumptions, not company facts.

Ask the interviewerWhy the answer changes the design
Chronological feed or personalized ranking?Ranking introduces feature freshness and candidate-selection contracts.
Follower graph sizes and celebrity skew?Fan-out-on-write may need a hybrid read path.
How quickly must deletion, privacy and blocks affect old feed entries?Hydration must enforce current visibility; cached IDs are not authority.

Use the Interview Playbook for the shared 45-minute sequence and fresher, intermediate, senior and staff evidence. Start with one complete operation. Extend the answer with the failure/recovery traces below, then defend a workload-specific alternative and a measurable rollout. Scope and evidence matter more than a large component list.

FB News Feed: Understand the building blocks

Choose a mechanism because it satisfies a requirement. These explanations describe the exercise design, not undisclosed implementation choices at the named company.

FB News Feed: Quick vocabulary

TermMeaning and role in this exercise
API: Application Programming InterfaceThe contract for requests, responses and errors between components. An API route does not itself enforce every business invariant.
URL: Uniform Resource LocatorNames a resource and access location. Normalize carefully and do not trust an imported address as a safe server fetch destination.
PK: Primary KeyThe declared row identity in a database schema; it does not automatically enforce every cross-row business rule.

FB News Feed: Fanout-on-write, fanout-on-read and hybrid feed

What it means: Write fanout prepares recipients’ candidates when a post is published; read fanout gathers eligible author posts when the viewer requests a page. A hybrid combines them.

Why this problem needs it: Audience skew makes one fanout policy inefficient for all authors.

How to use it: Choose the strategy by author audience and actual read/write heat, retain versioned candidates, and bound merge work on reads.

Example in this design: 100 posts/s at 200 followers gives 20,000 candidate writes/s; a million-follower author creates a different burst.

When it fits: Useful to trade candidate write amplification against read latency under skewed audiences.

Alternative and limits: A direct indexed read can fit small scale. Fanout is candidate preparation, not ranking, stable pagination or current privacy enforcement.

FB News Feed: Projection and materialized view

What it means: A projection is a derived read model built from authoritative facts; it improves a particular read path and can be rebuilt.

Why this problem needs it: Prepared candidates accelerate reading without owning the original post.

How to use it: Consume versioned facts with replay-safe updates, expose a watermark/revision, and compare or rebuild from the authoritative history.

Example in this design: A feed candidate can be rebuilt from post facts and may lag deletion.

When it fits: Useful when read shapes or volume justify duplicating computation/state.

Alternative and limits: Read authoritative rows directly for a simpler strongly current baseline. A stale projection must not grant revoked access or decide a strict inventory transition.

FB News Feed: Cache-aside, Redis and time to live (TTL)

What it means: A cache keeps reusable copies for faster reads. Cache-aside checks the cache, loads an authoritative source on a miss, then fills it. TTL is the declared entry lifetime.

Why this problem needs it: Frequently read pages can reuse ranking/candidate work under a declared freshness policy.

How to use it: Key by the correct tenant/object/version, retain an absolute freshness deadline, bound entry size, and apply the stated invalidation or version-fence policy. Redis is one possible in-memory implementation.

Example in this design: A cache hit still checks the visibility policy before showing a private post.

When it fits: Useful when repeated eligible reads justify memory and the tolerated staleness is explicit.

Alternative and limits: Direct indexed database reads may suffice. A cache is not automatically durable authority; shorter TTL does not prove immediate revocation.

FB News Feed: Access Control List (ACL) and current authorization

What it means: An ACL records which principals may perform specified actions on an object. Authorization evaluates the applicable current policy for this request.

Why this problem needs it: A cached candidate can outlive permission changes.

How to use it: Authenticate the caller, evaluate object/tenant membership and permission version at the required disclosure/mutation boundary, and declare caching/revocation behavior.

Example in this design: A viewer losing access is denied even if the old page still contains the post ID.

When it fits: Needed when object access can change while connections, projections or cursors remain alive.

Alternative and limits: Capabilities/signed grants can fit a bounded expiry policy. A valid cursor, cached candidate or open socket is not permanent permission.

Interview scope and guarantees

Publish posts, follow authors, read a ranked feed, and remove or restrict posts. Separate candidate freshness from authorization: a stale feed may omit a new post, but must not reveal a now-private post. Start with text and media references; media transfer is a separate path.

Capacity worksheet

Assume 10 million daily users open the feed 20 times: 200 million reads/day, about 2,315/s average and 11,574/s at 5× peak. One million posts/day with 200 followers creates 200 million inbox inserts/day. One author with 20 million followers can exceed that daily average in one burst.

Concrete API contract

Contract / pseudocode
POST /posts {text,mediaIds,visibility} -> {postId}
POST /follows {authorId}
GET /feed?cursor=... -> {items,nextCursor}
DELETE /posts/{id} -> 202

Data model and access paths

Contract / pseudocode
posts(post_id PK,author_id,created_at,visibility,version,deleted_at)
follows(follower_id,author_id); UNIQUE(follower_id,author_id); INDEX(author_id,follower_id)
inbox(user_id,sort_key,post_id,source_version); PK(user_id,sort_key); UNIQUE(user_id,post_id)
fanout_tasks(post_id,shard,cursor,state); PK(post_id,shard)
feed_session(session_id,viewer_id,candidate_ids,rank_version,expires_at)

Evolve a solution and explain each change

Three architecture decisions for FB News Feed, including the pressure each introduces.
Three architecture decisions for FB News Feed, including the pressure each introduces.
Read the diagram

Read on demand / Fetch recent posts from followed accounts and merge by stable ordering. / A user following many accounts requires excessive read work.; Fan out ordinary authors / Populate follower candidate lists asynchronously when a post is published. / A celebrity creates a huge write burst; projections may lag.; Use a hybrid feed / Merge cached candidates with high-fanout authors at read time and recheck visibility. / Ranking, pagination, and revocation still need defined semantics.

Open original
FB News Feed · architecture decisions
Three architecture decisions for FB News Feed, including the pressure each introduces.

Three architecture decisions for FB News Feed, including the pressure each introduces.

Step 1: Read on demand

Fetch recent posts from followed accounts and merge by stable ordering. A user following many accounts requires excessive read work.

Step 2: Fan out ordinary authors

Populate follower candidate lists asynchronously when a post is published. A celebrity creates a huge write burst; projections may lag.

Step 3: Use a hybrid feed

Merge cached candidates with high-fanout authors at read time and recheck visibility. Ranking, pagination, and revocation still need defined semantics.

Responsibility overview

Connected responsibilities for FB News Feed. Trace the authoritative and derived paths separately.
Connected responsibilities for FB News Feed. Trace the authoritative and derived paths separately.
Read the diagram

Reader to Feed API: request feed; Feed API to Post DB: current visibility; Author to Feed API: publish post; Post DB to Fanout worker: post outbox; Fanout worker to Candidate cache: project candidate IDs; Feed API to Candidate cache: read candidate list

Open original
FB News Feed · connected architecture
Connected responsibilities for FB News Feed. Trace the authoritative and derived paths separately.

Connected responsibilities for FB News Feed. Trace the authoritative and derived paths separately.

Worked end-to-end scenario

An ordinary author publishes p10. The post transaction stores content and an outbox entry; workers add its ID to follower candidate lists. A celebrity publishes p11, which stays in an author timeline and is merged at read time. A reader page merges and deduplicates these sources, applies visibility, and ranks a bounded candidate set. If a worker replays p10, the candidate key prevents a duplicate. Later the author removes a follower. The old candidate list may retain p10, so access must be checked when content is assembled. A cached candidate is never proof of current permission.

Why these access paths matter

Posts are indexed by author, creation order, and ID. Candidate lists are keyed by recipient and ordered post identity. Follow relationships need both follower and followee access paths for reads and fanout. Use a cursor tied to a ranking snapshot or explicitly tolerate live-feed movement; an offset across a changing ranked list can duplicate or skip items.

Build the baseline first

FB News Feed: baseline request paths.
FB News Feed · working baseline
Read the diagram

Author → post store → publication event; Feed reader → followed authors → recent posts; Authorization filter → ranking → response

Open original
FB News Feed · working baseline
FB News Feed: baseline request paths.

FB News Feed · working baseline

  1. Author → post store → publication event.
  2. Feed reader → followed authors → recent posts.
  3. Authorization filter → ranking → response.

Evolve the design under load

FB News Feed: additional scaling and recovery paths.
FB News Feed · scale and recovery paths
Read the diagram

Ordinary author → fanout workers → follower inboxes; High-fanout author → author timeline → read-time merge; Candidate merge → bounded ranker → stable page cursor

Open original
FB News Feed · scale and recovery paths
FB News Feed: additional scaling and recovery paths.

FB News Feed · scale and recovery paths

  1. Ordinary author → fanout workers → follower inboxes.
  2. High-fanout author → author timeline → read-time merge.
  3. Candidate merge → bounded ranker → stable page cursor.

Defend the hardest decision

Choose the push/pull threshold from fanout cost and observed reader activity, not a fixed celebrity label. Pushing to inactive users wastes writes; pulling every author for every read wastes latency. Merge both paths using post ID deduplication. Ranking a bounded candidate set is affordable, but a changing score can cause duplicates or gaps across pages. A session snapshot or stable cursor semantics makes that behavior explicit.

Failure and recovery analysis

Fanout workers fall behind while a celebrity publishes. Keep publication durable, protect read latency, and surface a freshness metric. Deletion events remove projections eventually, but the final response checks current visibility or an authoritative revocation layer. On follow changes, decide whether the next page uses the existing snapshot or starts a new feed session.

Security and privacy boundary

Apply block lists, visibility changes, and tenant boundaries after candidate retrieval. Avoid retaining deleted post text in secondary indexes indefinitely.

Interview follow-ups with reasoning

Question: What if the ranking service fails?

Show answer and explanation

Answer: Serve a chronological fallback from authorized candidates.

Question: How do you rebuild inboxes?

Show answer and explanation

Answer: Replay source events into a new projection generation and compare coverage before switching.

Question: How do you avoid expensive fanout retries?

Show answer and explanation

Answer: Checkpoint follower ranges and make (user,post) insertion idempotent.

Operate and verify the design

Feed p99, fanout age, ranking fallback rate and visibility-revocation delay.

Publish a celebrity post during fanout backlog and revoke an older post while readers paginate.

A second scenario to test transfer

An ordinary author has 500 followers and posts twice a day: precomputation creates about 1,000 candidate writes/day. A celebrity has 20 million followers and posts ten times: naive fanout creates 200 million candidate writes/day. Pulling that author’s recent posts during active readers’ requests can be cheaper, especially when many followers are inactive. Explain the resulting read merge cost.

How do you prevent an old feed entry from exposing a post after access is revoked?

Show answer and explanation

Answer: Treat the feed entry as a candidate and validate current visibility before returning content. Also propagate removal events to reduce stale work, but do not rely solely on eventual cache cleanup when the contract requires immediate revocation.

Compare alternatives

StrategyStrengthCost
Fanout-on-writeCheap common readsAmplified writes
Fanout-on-readCheap author writesRead-time merge
HybridHandles audience skewTwo paths and threshold policy
Visibility recheckProtects stale candidatesExtra read-path work

A design-changing exercise

Deleting a candidate entry fails after a privacy change. Can the post still appear?

Show answer and explanation

Answer: The serving path must enforce current visibility or a defined bounded permission policy. Projection deletion alone is insufficient protection.

Design workshop: choose hybrid fanout with a calculation

Core flows are publish, follow, fetch a ranked page and revoke visibility. Ads and ML model training are outside the baseline. Assume feed p95 under 200 ms, ordinary post projection within five seconds and current authorization before returning protected content. A missing fresh candidate is acceptable within that bound; a private post exposed to an unauthorized reader is not.

An author with F followers, active-reader fraction a, P posts/day and R feed reads/day per active follower costs roughly F×P candidate writes under push versus a×F×R author-timeline merges under pull. The costs are different operations, so compare measured write and merge cost, not only their counts. With F=20 million, P=10, a=0.05 and R=5, push is 200 million candidate writes/day while pull involves five million active feed-read merges. This motivates pull for that author; thousands of ordinary authors can still use push.

python
# A bounded candidate merge, before expensive ranking.
pushed = inbox_candidates(viewer, cursor)
pulled = merge_recent_timelines(celebrity_follows(viewer))
candidates = unique_by_post_id(pushed + pulled)
authorized = batch_filter_current_visibility(viewer, candidates)
ranked = rank(authorized, pinned_rank_version)
return freeze_session(ranked[:500], viewer, ttl_minutes=5)

A session stores viewer identity, ordered candidate IDs and rank version. The cursor is signed session ID plus offset; it is not an unconstrained timestamp. Pagination advances through the frozen list while rechecking current visibility, topping up from later candidates if privacy removals shorten a page. Expiry returns a reset response. New posts appear on refresh rather than shifting an existing session's page boundaries.

Push ordinary authors and pull celebrities. Author to Post authority: Publish p17 and outbox in one commit; Post authority to Fanout worker: Task carries author/post/version and shard cursor; Fanout worker to Fanout worker: Unique viewer/post insert; checkpoint bounded follower page; Feed reader to Post authority: Fetch celebrity recent posts during read merge; Feed reader to Post authority: Recheck visibility of pushed and pulled IDs; Feed reader to Feed reader: Rank once; freeze ordered candidate session
Push ordinary authors and pull celebrities.
Read the diagram

Publish p17 and outbox in one commit; Task carries author/post/version and shard cursor; Unique viewer/post insert; checkpoint bounded follower page; Fetch celebrity recent posts during read merge; Recheck visibility of pushed and pulled IDs; Rank once; freeze ordered candidate session

Open original
Push ordinary authors and pull celebrities
Push ordinary authors and pull celebrities. Author to Post authority: Publish p17 and outbox in one commit; Post authority to Fanout worker: Task carries author/post/version and shard cursor; Fanout worker to Fanout worker: Unique viewer/post insert; checkpoint bounded follower page; Feed reader to Post authority: Fetch celebrity recent posts during read merge; Feed reader to Post authority: Recheck visibility of pushed and pulled IDs; Feed reader to Feed reader: Rank once; freeze ordered candidate session

Push ordinary authors and pull celebrities.

The follower index needs both follower→authors and author→followers access paths. Shard fanout_tasks by post and follower-range; insert a batch and its checkpoint in one projection transaction. Retried batches use unique(user_id,post_id), not a newly generated sort key. Source versions reject stale deletion/republication events. If rank placement changes, update the candidate row rather than create another post identity.

Recovering a feed without leaking revoked posts. Fanout worker crashes mid-page / Replay from checkpoint; unique viewer/post key / No duplicated candidate; Celebrity posts during page 2 / Existing frozen session unchanged / Stable pagination until refresh; Post becomes private / Read-time ACL filter plus versioned removals / No protected payload or media URL; Candidate cache lost / Rebuild from posts/follows and task log / Slower reads; bounded fresh-feed lag
Recovering a feed without leaking revoked posts.
Read the diagram

Failure / Recovery / User-visible guarantee; Fanout worker crashes mid-page / Replay from checkpoint; unique viewer/post key / No duplicated candidate; Celebrity posts during page 2 / Existing frozen session unchanged / Stable pagination until refresh; Post becomes private / Read-time ACL filter plus versioned removals / No protected payload or media URL; Candidate cache lost / Rebuild from posts/follows and task log / Slower reads; bounded fresh-feed lag

Open original
Recovering a feed without leaking revoked posts
Recovering a feed without leaking revoked posts. Fanout worker crashes mid-page / Replay from checkpoint; unique viewer/post key / No duplicated candidate; Celebrity posts during page 2 / Existing frozen session unchanged / Stable pagination until refresh; Post becomes private / Read-time ACL filter plus versioned removals / No protected payload or media URL; Candidate cache lost / Rebuild from posts/follows and task log / Slower reads; bounded fresh-feed lag

Recovering a feed without leaking revoked posts.

Hot fanout authors use the pull path, but a reader following many celebrities can still create unbounded merges. Cap the number of timelines queried per request, cache eligible public author slices, fetch recent windows and define graceful freshness degradation. Operate on candidate IDs first; media and body hydration happen after authorization. Measure fanout lag, page fill ratio, stale-version rejection, ACL denials and celebrity merge time separately.

Exercise: p17 is fanout-delivered twice with two event IDs, then deleted, then an old publish event is replayed. How many visible copies should remain?

Show answer and explanation

Answer: Zero after deletion becomes authoritative. Candidate uniqueness handles duplicate insertion; a retained post version/tombstone rejects the old publish. The final ACL/deletion check protects the reader even before all projection cleanup completes.

Requirement trace and verification

RequirementImplementing design blockVerification link
R1 — Complete the primary user journey within the stated scope.P01–P04; P09–P10.V1 — Exercise the successful journey and the excluded/boundary case stated in the scope.
R2 — Preserve the problem's authoritative data invariant under concurrency.P05–P06; P11–P12; DD1.V2 — Run the race/replay case below and assert the invariant at the durable authority.
R3 — Meet the declared scale and API behavior without unbounded work.P05–P08; P13–P14; relevant overload deep dives.V3 — Exercise the API errors/retry identity and recompute the workload assumption that drives partition or capacity.
R4 — Recover from the named failure without losing or duplicating the user-visible outcome.P15–P16; deep dives; Operations contract.V4 — Crash a fan-out worker after a partial batch, replay it, and publish while paging; no duplicate entries and bounded recovery work.

Operational contract

AreaDecision and signals
SLIsFeed p99; fanout lag; cursor reset rate; visibility-filter rejects; celebrity merge work.
Overload limitsCap fanout batch size, recipient queue depth, candidate count, and per-request ranking budget.
RecoveryResume fanout from durable shard cursor; rebuild derived feed entries from posts/follows; recheck privacy at read.
Access controlsAuthorize every hydrated post against current audience and block state; scope social graph reads.
Dominant costFeed projection writes and candidate hydration/cache traffic.

Senior-level interviewer follow-ups

Question: How do privacy changes propagate to a feed entry already written into a follower's cache?

Show answer and explanation

Answer: Treat feed entries as candidate references, not permanent authorization. Recheck the current post visibility at read or hydration time and invalidate derived copies asynchronously; state the revocation latency target.

Question: A celebrity's post creates a fanout storm. How do you decide push versus pull?

Show answer and explanation

Answer: Estimate follower count, read rate, and freshness cost. Push ordinary authors, keep extreme fanout as pull candidates, and tune a threshold from measured write amplification and read latency.

A 60-second design answer

I would store posts and follow edges as authoritative state, then build a hybrid feed: push ordinary posts to recipient inboxes and pull high-fanout authors at read time. A ranked cursor pins a stable view, but visibility is checked against current privacy state. I would track fanout lag, candidate count, ranking cost, stale entries, and cache freshness.

Scaling Reads Kafka

Technical references

Kafka processing and external-sink boundaries.

PostgreSQL transaction isolation and concurrent updates.

Merge actual candidates under a stable browsing contract

A reader's projected ordinary-author inbox contains p9,p8,p6. A celebrity pull stream contains p10,p9,p7. Merge by the selected stable rank/order tuple, dedupe p9 and apply current visibility. If p8 is revoked, its stale inbox entry does not authorize it. A fixed feed generation can keep pagination stable; best-effort live ranking must admit possible shifts rather than claim snapshot semantics.

Contract / pseudocode
push candidates: p9,p8,p6
pull candidates: p10,p9,p7
unique merged order: p10,p9,p8,p7,p6
current ACL removes p8 -> p10,p9,p7,p6
push candidates: p9,p8,p6; pull candidates: p10,p9,p7; unique merged order: p10,p9,p8,p7,p6; current ACL removes p8 -> p10,p9,p7,p6
Merge actual candidates under a stable browsing contract
Read the diagram

push candidates: p9,p8,p6; pull candidates: p10,p9,p7; unique merged order: p10,p9,p8,p7,p6; current ACL removes p8 -> p10,p9,p7,p6

Open original
Merge actual candidates under a stable browsing contract
push candidates: p9,p8,p6; pull candidates: p10,p9,p7; unique merged order: p10,p9,p8,p7,p6; current ACL removes p8 -> p10,p9,p7,p6

Merge actual candidates under a stable browsing contract

One author with 10 million followers turns one post into up to 10 million fanout writes under naive push. A hybrid threshold trades that work for reader-time candidate merge. State the rate/latency assumptions and cap rebuild/celebrity work; a threshold is not universally correct. Deleted posts and follow/privacy changes require read filtering plus eventual projection cleanup/rebuild.

Show answer and explanation

Answer: A cached cursor must bind ranking/filter/generation context. Deduplication prevents repeated p9, but it does not by itself keep changing rankings stable between pages.

Decision review: FB News Feed

FB News Feed: What it is

A feed design chooses and orders eligible post candidates under a declared freshness, ranking and pagination contract.

FB News Feed: Why it is needed

Fanout and cache reuse reduce work, but neither establishes current visibility or a stable browsing order by itself.

FB News Feed: When to use it

Use eager fanout for justified bounded audiences and compare lazy/hybrid retrieval when large-author bursts dominate candidate writes.

FB News Feed: How to use it

Preserve authoritative post revisions, publish version-aware candidates and enforce the agreed visibility policy before content is disclosed. Bound candidate scans and pin a browsing generation when the product requires stable pages.

FB News Feed: Compare an alternative

Fanout-on-read lowers write amplification but increases read/merge work; fanout-on-write speeds common reads but increases storage and celebrity burst costs. Compare the same freshness and authorization requirements.

FB News Feed: Worked decision exercise

The following inputs and policies are original exercise assumptions; they are not measurements or undisclosed company behavior.

At 100 posts/s and 200 followers per ordinary post, eager fanout adds about 20,000 candidate writes/s. One million-follower author can create a million-entry burst. A viewer then loses access to a post still present in its cached candidate page.

FB News Feed: 100 posts/s x 200 followers = 20,000 writes/s; Celebrity burst can add 1,000,000 candidates; Candidate cache may outlive a visibility change; Current policy decides what content can be returned
FB News Feed: a concrete state and recovery trace under the exercise assumptions.
Read the diagram

100 posts/s x 200 followers = 20,000 writes/s; Celebrity burst can add 1,000,000 candidates; Candidate cache may outlive a visibility change; Current policy decides what content can be returned

Open original
FB News Feed: worked example
FB News Feed: 100 posts/s x 200 followers = 20,000 writes/s; Celebrity burst can add 1,000,000 candidates; Candidate cache may outlive a visibility change; Current policy decides what content can be returned

FB News Feed: a concrete state and recovery trace under the exercise assumptions.

Does removing a stale candidate asynchronously satisfy immediate visibility revocation?

Show answer and explanation

Answer: Only if the serving policy independently enforces the required current authorization. If that authority is unavailable, choose the allowed failure response; a stale projection cannot grant access. Hybrid fanout changes candidate cost, not this rule.

FB News Feed: Check the design

Measure candidate work, fanout lag, privacy rejection and page duplication/omission under rebuild. Test a revocation between candidate retrieval and disclosure.

Your study notes