Social Network

Social Media Platform

Design the core of a social network: follows and friendships, posts with visibility rules, a news feed that mixes push and pull delivery, likes, blocks and private messages.

Overview

A social network lets people connect, share posts and read a feed of what the people they follow have posted. In a low level design interview the scope is the object model inside one service: users, the social graph (who follows whom, who is friends with whom), posts with a visibility setting, likes and comments, a feed, blocks, and direct messages.

The problem tests three things. First, whether you keep the social graph separate from posts and profiles, so each part has one job. Second, whether you know the two ways to build a feed (copy each new post to followers when it is written, or gather posts when the feed is read) and when to mix them. Third, whether privacy rules hold on every read path, including posts that were delivered before a friendship ended or a block was added.

A strong answer scopes the problem quickly, draws the graph and the post as separate classes, names the fan-out choice with its cost, and writes a program whose tests show a friends-only post hidden from a follower who is not a friend.

Scoping the problem

  • Follow (one way), friend (two way), or both? — Decides the graph's shape and who sees friends-only posts — Both: a friendship implies a follow in each direction
  • Which visibility levels does a post have? — Every read must check it — Public, friends, private
  • Is the feed newest first or ranked? — Ranking must be pluggable if it is ever more than time — Newest first, with ranking as a follow-up
  • How many followers can one account have? — Decides push, pull or a mix for the feed — Most have few; a few have very many
  • What does a block do? — It must cut follows, friendships, feeds and messages — Removes the link both ways and hides everything
  • Are messages one to one or group chats? — Group chats add a conversation entity — One to one in the core
  • Do we need persistence and many servers? — Changes the storage layer, not the classes — Follow-up, not the core

Core entities

The graph holds only ids and relationships. A post holds only its own content and reactions. The network ties them together and is the one place that decides what a viewer may see.

Push, pull, or both

A feed can be built two ways. With push (also called fan-out on write), each new post id is copied into every follower's inbox when it is written, so reading a feed is cheap. With pull (fan-out on read), nothing is copied, and the feed is gathered from every followed account when it is read.

  • Push to every follower — One write per follower — Read one inbox — An account with millions of followers makes millions of writes per post
  • Pull at read time — One write — One read per followed account — A user who follows thousands of accounts waits on thousands of reads
  • Mix: push for most, pull for accounts above a follower threshold — Bounded — Inbox plus a few large accounts — Two code paths to test

The code below uses the mix. create_post pushes the id into each follower's inbox unless the author has more followers than celebrity_threshold. feed reads the inbox, adds the latest posts of any followed large account, filters by visibility, and ranks.

Who can see a post

The visibility rule runs on every read. Checking it when the post is pushed would be wrong, because a friendship can end or a block can be added after the push.

The demo in the implementation builds this small network, with celebrity_threshold=2.

  • 1 — Ana and Ben become friends; Cy follows Ana; four users follow Star — Star is a large account, Ana is not
  • 2 — Ana posts public (1), friends-only (2), private (3); Star posts (4) — Posts 1 to 3 are pushed; post 4 is not
  • 3 — Ben reads his feed — 4, 2, 1: he is Ana's friend
  • 4 — Cy reads his feed — 4, 1: a follower, not a friend
  • 5 — Ben reads two posts, then the next page with before_id — The pages join to 4, 2, 1 with no repeat
  • 6 — 60 threads like post 1 (50 distinct users, one user 10 more times) — Exactly 50 likes
  • 7 — Ana blocks Cy — Cy's feed drops post 1; Cy cannot message Ana
  • 8 — Ana and Ben unfriend (both still follow) — Post 2 is still in Ben's inbox but no longer in his feed

Friend requests

A friendship takes two steps, so it has states. Only the person who received the request can accept it, and a block clears any pending request.

What you will be able to do

  • Scope a social network in a few questions and draw the graph, the post and the network as separate classes.
  • Compare push, pull and mixed feed delivery by the cost to post and the cost to read.
  • Enforce visibility and blocks on every read path, and explain why the check cannot happen at write time.
  • Make likes safe under concurrency and keep them idempotent.
  • Page through a feed with a cursor instead of an offset.

Functional requirements

  • follow(a, b) and unfollow(a, b); request_friend(a, b), accept_friend(a, b) and unfriend(a, b), where accepting also adds a follow in both directions
  • create_post(author, text, visibility, now) with visibility public, friends or private
  • like(user) and comment(user, text) on a post; a user likes a post at most once
  • feed(viewer, now, limit, before_id): posts from followed accounts and the viewer, visibility checked, ranked, paged with a cursor
  • block(a, b) removes follows, friendships and pending requests both ways and hides posts and messages
  • send_message(sender, recipient, text) for one-to-one messages, refused between blocked users

Non-functional requirements

  • Posting cost stays bounded for accounts with very many followers (pull for those above a threshold)
  • Reading a feed does not scan every post in the system: inbox ids plus a few large accounts
  • Visibility and blocks are enforced on every read, so a later block or unfriend takes effect at once
  • Safe under concurrency: the graph, the network and each post have their own lock; likes are never lost
  • New ranking rules are new Ranker classes; the feed code does not change

Interview questions

  • An account has ten million followers. What happens when it posts?
  • Ben was Ana's friend when her friends-only post was pushed to his inbox. Then they unfriend. Can he still see it?
  • How do you add a ranked feed without rewriting feed()?
  • Two thousand people like the same post in one second. How do you keep the count right?
  • How do you page through a feed so new posts do not cause repeats?
  • How would this look with a real database behind it?

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio