Facebook0/66 done
Part 3 · System design · Real products

Facebook

Users add friends, post, and see a ranked news feed. Suggest people they may know. Billions of users.

In plain words

Your feed isn't newest first. Facebook gathers a few thousand recent posts from friends and pages, drops anything you're not allowed to see, then scores each one: how close you are to the person, how much people are reacting, how old it is. You see the top 20.

People you may know works like a party. You know Ana and Bob. Ana and Bob both know Cat. You've never met Cat, but two of your friends have, so Cat goes at the top of your suggestions.

Examples

  • A post from your sister an hour ago beats a two day old post from someone you never talk to.
  • A post with 200 likes can beat a close friend's quiet post.
  • The friend graph is stored as edges sharded by user, behind a huge cache (Facebook's is called TAO).
  • If ranking is slow, show a simple newest first feed instead of an empty screen.

1. Requirements

Functional

Non functional

Questions to ask

2. Estimates

users2B daily, average 300 friends
feed loadsabout 10 per user per day: 230k per second
candidatesa few thousand candidate posts per feed load, ranked down to 20

3. API

GET  /feed?cursor=...                  [posts], nextCursor
POST /posts { text, audience }          { id }
POST /friends/requests { userId }       202
GET  /suggestions                       [people with mutual count]

4. Data model

posts(id, author_id, audience, created_at)
friendships(user_a, user_b)   the social graph, in a graph store (TAO style), heavily cached
engagement: likes, comments, views as events for ranking
suggestions:{user} precomputed daily

5. High level design

Follow one request at a time, top to bottom.

Load the feed

  1. ClientGET /feed
  2. Feed servicegathers candidate posts from friends and pages
  3. Graph cache (TAO style)who are my friends, what did they post
  4. Privacy filterdrops posts you can't see
  5. Rankercloseness x engagement / age, keep the top 20
  6. Clientrenders, cursor for more

Suggest friends

  1. Daily batchfriends of friends per user
  2. Count mutual friendsskip current friends and blocks
  3. Suggestions storetop results per user
  4. ClientGET /suggestions

6. Deep dives

How is the feed built?

Gather candidates from friends and pages, filter by privacy, score each by how close you are to the author, how engaging the post is and how fresh it is, then show the top. Cache the result for a short time.

How do you suggest friends?

Friends of friends, counted by mutual friends, skipping current friends and blocked people. Computed in a daily batch, plus signals like same school or contacts.

How do you store the social graph?

As edges in a graph store sharded by user id, with a big read through cache in front. Most reads are "friends of X", so keep each user's edges together.

How do you enforce privacy?

Check the audience at read time for each candidate, after gathering and before ranking. Never trust a cached feed across a privacy change; invalidate it.

See the core idea run

Core logic (JavaScript, tested)

// Friends of friends ("People you may know"): count mutual friends, skip people you already know.
function suggest(friends, me, limit = 3) {
  const mine = friends.get(me) ?? new Set();
  const mutual = new Map();
  for (const f of mine)
    for (const ff of friends.get(f) ?? [])
      if (ff !== me && !mine.has(ff)) mutual.set(ff, (mutual.get(ff) ?? 0) + 1);
  return [...mutual].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)).slice(0, limit);
}

// Ranked feed: score = how close you are to the author x how engaging x how fresh.
const score = p => p.affinity * (1 + p.likes / 10) / (1 + p.ageHours / 6);
const rank = posts => [...posts].sort((a, b) => score(b) - score(a)).map(p => p.id);

7. Failures

Ranking service slowFall back to a simple recency order rather than a blank feed.
Graph cache cold after a deployWarm the hottest users first and cap load on the graph store.
A post goes viralCounters are sharded and approximate; exact numbers are fixed later in batch.

8. Trade-offs

Wrap up

Say out loud: Feed is gather, filter, rank: candidates from friends, a privacy check, then a score of closeness times engagement divided by age, top 20 shown. The friend graph is stored as edges sharded by user, with a big cache. People you may know is friends of friends ranked by mutual friends, computed daily.