System design sample solution

System design: design a news feed

A step-by-step system design answer you could actually give in 60 minutes.

System design interview · Sample 60-minute answer · Not Meta's actual design · Independent, not affiliated with Meta

The system design question

Design the news feed. People see recent posts from friends and pages they follow, ranked so the most interesting are near the top, and the feed should load quickly.

Agree on the scope (5 minutes)

Say up front what you're covering.

We'll designWe'll skip
Publishing a postAds in the feed
Getting it into followers' feedsComments and likes themselves
Ranking the feedUploading photos and video
Loading the first screen quicklyPrivacy rules beyond 'run the check'

Then agree on what "good" means:

  • Fast: the first screen of the feed loads in about 200 ms on the server side.
  • Fresh enough: a friend's post shows up within a few seconds to a minute.
  • Relevant: the most interesting posts are near the top, even when they aren't the newest.
  • Handles celebrities: someone with 100 million followers posting doesn't knock anything over.

Rough numbers (5 minutes)

Assumptions, not real figures: 2 billion people a day, 10 feed loads each, 1 billion new posts a day, about 300 friends and pages each, and a few accounts with 100 million followers. Meta's design round is often 45 minutes, so get through this in a couple of minutes.

~230K
feed loads a second
~12K
new posts a second
~3.5M
feed inserts a second if we push everything
~16 TB
of feed lists in cache
QuestionRough mathWhat it means
How many feed loads?2 billion × 10 ÷ 86,400About 230K a second, around 700K at peaks
How many posts?1 billion ÷ 86,400About 12K a second
What if every post is pushed to every follower?12K × 300 followersAbout 3.5 million writes a second. Big, but doable for normal accounts
And one celebrity post?1 post × 100 million followers100 million writes for one post. Pushing that doesn't work
How much to keep a feed per person?2 billion × 500 post IDs × 16 bytesAbout 16 TB. Fits in a big cache cluster

The overall design (10 minutes)

Posterpublishes a postPost storesaved onceFan-out workerspush IDs to followersFeed servicemerge, check, rankViewerfirst screen of posts
Posts are saved once, their IDs are pushed into followers' feed lists, and the feed service merges in celebrity posts and ranks when someone opens the app.
  1. A new post is saved once in the post store, and an event goes onto a queue.
  2. Fan-out workers look up the poster's followers and add the post ID to each follower's feed list in a cache. Accounts with huge followings are skipped.
  3. When someone opens the app, the feed service reads their feed list, pulls recent posts from the few huge accounts they follow, and merges them.
  4. It runs the privacy check, scores the candidates, and returns the top 20 or so.
  5. The app fetches post details, photos and counts in one batch, with media coming from a CDN.

What the apps need to do

ActionWho does itWhat's sent
Publish a postThe posterContent, media IDs and the audience
Get my feedThe appA cursor for where you left off, and how many posts
Mark posts as seenThe app, in the backgroundPost IDs that were on screen
Follow or unfollowAnyoneThe account to follow

What we store and where

DataWhere it goesWhy
PostsPost store, split by post ID, with a cache in frontWritten once, read many times
Who follows whomGraph database, split by userFan-out needs followers, feed loading needs followees
Feed listsCache cluster, split by userThe latest few hundred post IDs per person, ready to read
Seen postsKey-value store, kept a few daysSo the same posts don't keep coming back to the top
Engagement signalsEvent stream into a features storeInputs for ranking, like how often you interact with someone

Step 1: Push, pull, or both (12 minutes)

Push (fan-out on write) means copying each new post ID into every follower's feed list as soon as it's posted. Reading is then one lookup. Pull (fan-out on read) means building the feed when someone opens the app by fetching recent posts from everyone they follow. Writing is cheap, but reading means 300 lookups and a merge on every load.

With 230K reads a second, pull everywhere is too slow. With celebrities, push everywhere is too expensive. So mix them: push for normal accounts, pull for accounts above some follower count, say 10,000. Each viewer follows only a handful of huge accounts, so pulling those at read time is a few extra lookups.

The fan-out runs through a message queue, so posting returns right away and the work happens in the background. Workers handle followers in chunks and can be added when the queue grows.

Don't push to people who aren't there

A lot of followers haven't opened the app in weeks. Skip pushing to anyone inactive for, say, 30 days. If they come back, build their feed with a pull the first time, then they're back on push.

Step 2: Ranking (10 minutes)

Ranking happens in stages, because scoring with a heavy model is too slow for thousands of posts. First, gather candidates: the latest few hundred from the feed list plus the pulled celebrity posts. Drop anything the viewer can't see or has already seen.

Then score each one. A simple version is a weighted sum of a few signals: how often you interact with the author, how old the post is, how much engagement it's getting, and what kind of post it is. A real system would use a model that predicts the chance you'll like, comment or share, but you don't need to design the model in this round.

Sort by score, and use a small heap if you only need the top 20. Then apply a few rules on top, like not showing three posts from the same person in a row.

  • Keep the ranked list for that session in a cache, so scrolling down reads the next page from it without ranking again.
  • Fresh posts arriving mid-session go into a 'new posts' banner rather than reshuffling what the person is looking at.

Step 3: Loading fast (8 minutes)

Feed lists, post objects and counts like likes all live in caches. The feed service fetches the 20 posts it needs in one batched call, not 20 separate ones. Like counts can be a little behind, which nobody notices.

Use a cursor for paging, the ID and score of the last post shown, so new posts don't make you see duplicates as you scroll. Return about 20 posts and let the app fetch the next page before the person reaches the bottom.

Everything is split by user ID, so one person's feed is one cache lookup on one machine. Photos and videos come from a CDN, so the feed response itself stays small.

Choices you should be able to defend

We choseInstead ofBecauseWe'd reconsider if
Push for most accounts, pull for huge onesPure push or pure pullFast reads without 100 million writes for one postAlmost nobody had huge followings, so pure push was simpler
Fan-out through a queueWriting to followers' feeds while postingPosting stays fast, and fan-out can lag a bit under loadWe needed posts to appear everywhere instantly
Ranking at read timeRanking when posts are pushedScores depend on the viewer and change as engagement comes inRanking cost got too high, so we'd precompute a rough score
Only keeping a few hundred IDs per feedKeeping everyone's whole historyNobody scrolls that far, and memory is expensivePeople often scrolled back days, so we'd page older posts from the database

What could go wrong (5 minutes)

What happensWhat we do about it
Fan-out workers fall behindPosts show up in feeds late, but nothing's lost. Add workers. The poster's own feed reads their post straight away
A feed cache node diesRebuild those feeds with a pull on the next load. It's slower once, then cached again
A celebrity posts and millions refresh at onceTheir post is pulled from a cache, so it's one hot key with lots of copies, not millions of database reads
The ranking service is slowFall back to newest first. A plain feed beats a blank screen
Someone deletes a postRemove it from the post store. Feeds still hold the ID, but it's dropped when the post can't be loaded

Follow-up questions (5 minutes)

How would you add ads?

Treat ads as another candidate source that gets merged in at fixed spots, with its own ranking and its own limits on how often ads show.

What if someone unfollows a person?

Stop new fan-out to them, and filter that author out at read time. Old IDs in the feed list fade out on their own.

How do you stop the same viral post showing up again and again?

The seen-posts store drops anything the person has already scrolled past, and the ranking rules limit repeats from the same source.

How the 60 minutes add up

MinutesWhat you're doing
0–5Agree on what you're building
5–10Rough numbers
10–20Draw the overall design
20–32Push, pull, or both
32–42Ranking
42–50Loading fast
50–55What could go wrong
55–60Follow-up questions

Key concepts used here

Further reading

We wrote this sample answer ourselves.

Practice Loop is independent and isn't affiliated with or endorsed by Meta.