SDSystem design
Start learning free

LESSON 85 OF 140 · PRACTICE PROBLEMS

Facebook News Feed

Read the written walkthrough

SYSTEM DESIGN · INTERVIEW WALKTHROUGH

Design the Facebook News Feed: System Design Interview Practice

The problem

"Design the Facebook News Feed": the posts from your friends, the Pages you follow and the groups you're in, scrolled every time you open the app. Park Messenger and ads: each is a system of its own.

This practice problem reuses the pattern of Twitter at Scale. What's new: a friendship is two-way and capped at 5,000 friends, the feed is ranked rather than newest first, every post has an audience, and a refresh should show posts you haven't seen.

The numbers

From the interviewer: 2 billion daily users, each posting about 0.5 times a day and opening the feed about 10 times a day, with about 200 friends on average. Round a day to 100,000 seconds (86,400 really).

  • Posts: 2 billion × 0.5 = 1 billion a day, about 10,000 a second (about 12,000 with 86,400).
  • Pushes: each post goes to about 200 friends, so about 2 million pushes a second (about 2.3 million exactly). Using the 5,000 cap for every post would give 50 million: the cap is the most, not the average.
  • Feed opens: 2 billion × 10 = 20 billion a day, about 200,000 a second.

Push or pull: friends are capped

As in Twitter, a new post's id is pushed into each reader's ready feed in a cache, and huge accounts are pulled at read time. The difference is the cap: a friendship needs both people to agree, and nobody can have more than 5,000 friends. So the most expensive friend's post costs 5,000 pushes: 25× an average post, and 20,000× less than a Twitter celebrity's 100 million. No friend is ever a celebrity, so friends' posts are always pushed. Store a friendship as two rows, Ana → Ben and Ben → Ana, so "Ana's friends" is one lookup.

Pages and groups have no cap. A news Page with 40 million followers would cost 40 million writes per post. Store those posts once, and when someone opens the feed, pull the latest from their big Pages and groups and merge them in.

Ranking: not newest first

For each open, the feed service gathers a few hundred candidates: the ids in the reader's feed cache plus the latest posts of their Pages and groups. A ranking service scores each one, and the feed sends the top 10 or so. A toy score multiplies affinity (how close the reader is to the author), engagement (the likes and comments the post is drawing) and freshness (higher when newer):

post              age        affinity  engagement  freshness  score
Ben's photo       5 hours    5         3           2          30
News Page video   1 hour     2         4           3          24
Dee's post        2 hours    4         1           3          12
Cy's status       just now   1         2           4          8

Newest first would put Cy's status on top; ranked, it comes last. Real systems learn the weights with a model. Facebook's early ranking, publicly known as EdgeRank, was described the same way: affinity, a weight for the type of story, and time decay, multiplied.

Scoring at read time

Scores keep changing: likes pile up, and every post loses freshness by the hour. Scoring once at push time would freeze a post's likes and never let it age, and pulled posts are never pushed at all; a nightly batch job would leave today's posts unranked until tonight. So candidates are scored when the reader opens the feed. That costs 200,000 opens a second × 500 candidates = 100 million scores a second, which is why ranking is a ranking service of its own, sized separately, and why candidates are capped at a few hundred.

Privacy: check the audience on every read

Every post stores its audience: public, friends, or a custom list such as Close friends. Say Cy posts to her friends, then an hour later narrows it to Close friends, a list without Ana: the id is already in Ana's feed cache. Before ranking, the feed service drops every candidate whose current audience doesn't include the reader. That one cheap check catches edited audiences, unfriends and blocks, for pushed and pulled posts alike.

Cleaning the id out of up to 5,000 feeds saves space, but one missed write would leak the post, so it can't be the only guard. A "hidden" flag for the app to obey is worse: the post has already reached the phone.

Seen posts: a refresh shows something new

Ana reads her top 10 and opens the feed again 5 minutes later. Few new posts have arrived, so the same 10 would win again. Keep a seen set per person, the ids shown in the last few days, beside her feed in the cache, and drop them (or rank them lower) at the next read: the posts just below the top 10 move up.

"Only posts newer than the last visit" fails because a ranked feed isn't in time order: this morning's 11th-best post would never be shown. Deleting shown ids from the cached list misses the pulled posts, which come back on every read.

Same pattern as Twitter at Scale

The engine is Twitter's: a queue of new posts, fan-out workers pushing ids into a feed cache split by user id, and huge accounts pulled at read time and merged in. Pages and groups play the celebrities, and the busy path is still the read.

Summary

  • Scope: friends (two-way, at most 5,000), Pages and groups; a ranked feed.
  • Data: each post keeps its audience; a friendship is stored both ways.
  • Numbers: about 2 million pushes and 200,000 feed opens a second.
  • Scale: friends' posts always pushed (5,000 at most), big Pages and groups pulled.
  • Ranking: a few hundred candidates scored at read time by a ranking service; the top 10 shown.
  • Privacy: every candidate's current audience checked at read time.
  • Seen posts: a seen set per person, so a refresh shows something new.
Keep going with system designInteractive lessons from the building blocks to Twitter, Uber and payments, the way interviews ask. Free to start.
Start learning free