SDSystem design
Start learning free

LESSON 6 OF 140 · FOUNDATIONS

The Interview Framework

The 8 steps, on a like button Read the written walkthrough

SYSTEM DESIGN · INTERVIEW WALKTHROUGH

System Design Interview Framework: 8 Steps on a Like Button

The problem: one line and 45 minutes

A system design interview starts with one sentence, such as "Design the like button," and about 45 minutes. With no single right diagram, many people freeze or start drawing boxes at once. Both cost points.

Interviewers grade how you get there. Three habits matter most:

  • Asking before designing. A few minutes of questions keep you from building the wrong system.
  • Numbers that change a decision. An estimate earns points when it steers the design, not for its decimals.
  • Trade-offs said out loud. Every choice has a price, and naming it shows you see it.

A fixed order of steps makes these habits automatic. Every design lesson in this course follows the same 8 steps: Scope, Data, API, Busy path, Numbers, Services, Scale, Deep dives, then a short recap. Here they are on a tiny system: the heart under a post and the count beside it.

How it works: the 8 steps

1. Scope

Agree on the smallest version that is still useful. For the like button, version 1 is like a post, unlike it, and see the count. Name what you leave for later: the list of who liked a post, notifications, other reactions. Spend about 5 minutes here.

2. Data

List the records version 1 needs. A like is one small record: user + post. Each post also keeps its like count ready, because every view shows it and counting a popular post's likes one by one would be slow. Names, photos and the posts themselves live elsewhere; a like points to them by id.

3. API

One call per feature:

POST   /posts/42/like     → 200 OK
DELETE /posts/42/like     → 200 OK
GET    /posts/42/likes    → 200 OK   {"count": 1204}

The paths name only the post. Who is liking comes from the sign-in token sent with every call, never from the path or the body, or anyone could like as someone else. The count call returns the number, not the list of likers: a viral post has millions. The app also needs to know whether you liked a post, to draw your heart filled; that's one lookup by user and post.

4. The busy path

Find the request that runs most often. Most people scroll past a post without tapping the heart, but every post they see shows its count. So reading the count is the busy path, the one that must stay fast.

5. Numbers

Ask for the traffic, or propose it. Say 1 billion post views a day and 50 million likes a day:

  • Count reads: 1 billion ÷ 86,400 seconds ≈ 12,000 a second (1 million a day is about 12 a second).
  • Likes: 50 million ÷ 86,400 ≈ 600 a second. Reads outnumber likes 20 to 1.
  • Busy hours: about 5× the average, so about 60,000 count reads and 3,000 likes a second.
  • Storage: about 18 billion likes a year. At about 100 bytes a like with its index, roughly 2 TB a year.

Keep this step to a few minutes: the ratio is what matters, because it says where to spend the design.

6. Services

On one server, a rush of views slows down saving likes, and you can't add servers for just one side. Split it: a Like service saves and removes likes and updates each post's count, and a Count service answers every post view with its count. Both share the likes database, and each side gets as many servers as its own traffic needs.

7. Scale

At busy hours the Count service sends about 60,000 reads a second to the database, and one database server answers about 5,000 simple lookups a second: 12 times too many. Two databases would only reach about 10,000.

The fix is a cache of counts in memory. One cache server answers about 100,000 lookups a second, and popular posts get most of the views. If the cache answers, say, 95% of reads, about 3,000 a second reach the database, under its limit. The trade-off to say out loud: a cached count can be a few seconds old, which nobody minds on a like count. (Whether you liked a post is a per-user lookup, spread evenly, so it scales another way: splitting the likes over about a dozen database servers by key, as the Sharding lesson shows.)

A viral post adds a second problem: its one count gets every write. A million likes in an hour is about 300 updates a second on one row, each waiting for the one before. A common fix is a counter updated in batches: add up the post's new likes for a few seconds, then write the total once. At 5 seconds, that is one write instead of about 1,400. The Distributed Counter lesson builds this in full.

8. Deep dives

The interviewer picks a hard part and you go deeper. A classic: one person liking twice. User 7 taps the heart on post 42; the POST is saved and the count goes from 1,204 to 1,205. But the answer is lost on a slow network, so the app sends the same POST again, and the count goes to 1,206.

The fix: make (user, post) the key of a like. The database keeps one row per key, so saving the same pair again changes nothing, and the count moves only when a row is really added or removed. The call is now idempotent: sending it twice does what sending it once does.

start               count 1,204
POST   (new)        count 1,205
POST   (repeat)     count 1,205   the key is already there
DELETE (found)      count 1,204
DELETE (repeat)     count 1,204   nothing to remove

Two tempting fixes fail. Turning off the heart in the app doesn't stop retries or other clients. Checking "does this like exist?" before saving leaves a gap: two requests at the same moment both check, find nothing, and save.

The choices and their trade-offs

  • Time per step. One plan for 45 minutes: scope 5, data 2, API 3, busy path 2, numbers 3, services 10, scale 8, deep dives 10, recap 2. About 28 minutes go to services, scale and the deep dives, where the trade-offs are.
  • Store the count, or count the likes. Counting rows is always exact but slow for big posts. A stored count is one read, but every like and unlike must keep it in step.

Where it shows up in design interviews

Everywhere. "Design a URL shortener", "design Twitter" and "design a chat app" are the same 8 steps with different answers. Interviewers often steer: they may hand you the numbers or jump to a deep dive early. Follow them, and keep the steps as a checklist.

Common interview questions

How should I start a system design interview?

With questions, not boxes. Agree on version 1's features and what is out of scope, then confirm the rough scale.

How precise should my estimates be?

Rough: round numbers, done in a few minutes. An estimate is worth it when it changes a decision, like "count reads are 20 times the likes, so the counts need a cache."

How would you stop one user from liking a post twice?

Make (user, post) the key of the like record, so a repeated save changes nothing, and change the count only when a row is really added or removed. That makes the call idempotent, so retries are safe.

How would you count likes on a viral post?

Serve the count from a cache, since reads far outnumber likes, and add up new likes in batches so the count is written every few seconds instead of hundreds of times a second. The count may lag a little, which is fine for likes.

Summary: the 8 steps on a like button

  1. Scope: like, unlike, see the count; who liked it comes later.
  2. Data: a like is user + post, and each post keeps its count.
  3. API: POST and DELETE /posts/42/like, GET /posts/42/likes.
  4. Busy path: reading the count on every post view.
  5. Numbers: about 12,000 count reads and 600 likes a second.
  6. Services: a Like service writes, a Count service reads.
  7. Scale: a cache of counts, and batches for a viral post.
  8. Deep dives: (user, post) as the key, so a double like counts once.

When an interviewer says "design X", walk the same 8 steps in the same order.

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