Free preview

Building Blocks and High-Level Design

In one line: the design splits one apparent job — "show the user a feed" — into two services, and the reason is the same asynchrony that licenses everything else in this chapter.

Building blocks

BlockRole
DatabasePosts, generated newsfeeds, user metadata, and relationships
CacheFrequently accessed posts, newsfeeds, and user metadata
Blob storageMedia content — images and videos
CDNDelivers content to end users, reducing delays and back-end load
Load balancersDistribute millions of incoming requests across servers

The two tasks

Primarily, the newsfeed system is responsible for two tasks:

  1. Feed generation: the newsfeed is generated by aggregating friends' and followers' posts based on some ranking mechanism.
  2. Feed publishing: when a feed is published, the relevant data is written into the cache and database. A post containing the data from friends and followers is populated in a user's newsfeed.
ComponentDetail
UsersMake a post with some content, or request their newsfeed
Load balancerRedirects traffic to one of the web servers
Web serversEncapsulate the back-end services. Enforce authentication and rate limiting, and redirect traffic to other services
Notification serviceInforms the newsfeed generation service whenever a new post is available from one's friends or followers, and sends a push notification
Newsfeed generation serviceGenerates newsfeeds from the posts of followers/friends and keeps them in the newsfeed cache
Newsfeed publishing servicePublishes newsfeeds to a user's timeline from the newsfeed cache. Appends a thumbnail of the media content from blob storage and its link
Post serviceStores a created post in the post database and cache. Media content goes to blob storage

Generation and publishing are separate because they run at different times

The split looks like arbitrary decomposition. It is not — it is the write path and the read path, and they are separated precisely so the expensive one can be asynchronous.

Generation is the expensive half: read the follow graph, fetch candidate posts, run ranking, write the result to cache. Per Lesson 4 it can be triggered by a post (push) or by a request (pull), and per Lesson 2's requirement it "can be executed asynchronously to precompute user feeds."

Publishing is the cheap half: read the cached feed, hydrate it with post and user data, deliver.

GenerationPublishing
Triggered byA new post, or a cold readA user opening the app
CostHigh — graph traversal, rankingLow — cache read plus hydration
Latency budgetNone (async)Under 2 seconds
Scales withPosts x connectionsReads

That difference in latency budget is the reason they cannot be one service. A single component doing both would be sized for the worst case of both, and the expensive half would sit inside the user's request.

Split components by their latency budget, not by their subject matter. The same argument produced Uber's location-manager-versus-trip-manager split and Twitter's asynchronous fan-out.

The notification service is the fan-out trigger, and its description hides that

"Informs the newsfeed generation service whenever a new post is available from one's friends or followers, and sends a push notification."

Two very different jobs in one sentence, and the first is far more important than it sounds.

Informing the generation service is what makes push fan-out happen. When Bob posts, something must tell the system to update his followers' feeds. That trigger is Lesson 4's entire write path, and here it is a clause.

Sending a push notification is the phone alert — a user-facing feature with completely different requirements: delivery guarantees, per-user preferences, rate limiting so people are not spammed, and quiet hours.

Bundling them is a modelling error. The first is internal fan-out orchestration at millions of events per second; the second is outbound messaging to devices with policy attached.

In practice both subscribe to the same POST_CREATED event, which is the right structure — one event, multiple independent consumers, exactly the pub-sub shape the Twitter and Uber chapters used. But they are consumers, not one service.

'Appends a thumbnail and its link' is the reference model, made concrete

The publishing service "appends a thumbnail of the media content from blob storage and its link."

That single phrase is Lesson 3's correction in practice. The feed does not contain the 2 MB video — it contains:

<Post_ID, User_ID>  ->  hydrate  ->  text + thumbnail + LINK to full media

So the feed payload carries a small thumbnail for rendering the list and a link the client follows only if the user engages. The 2 MB video is fetched from the CDN, once, by the small fraction of viewers who actually watch it.

Two consequences worth naming:

Storage is per-object, not per-feed. The video exists once in blob storage regardless of how many feeds reference it — which is why Lesson 3's 56 PB over-counts by two orders of magnitude.

Bandwidth is demand-driven. You do not pay egress for media nobody opens. In a feed where most items are scrolled past, that is the difference between viable and ruinous.

Deliver a cheap representation eagerly and the expensive one lazily. The same instinct as that building block's lazy tile loading.

Web servers as a facade — worth one sentence, not more

"Web servers encapsulate the back-end services and work as an intermediate layer between users and various services. In addition to enforcing authentication and rate limiting, they redirect traffic to other back-end services."

This is an API gateway by another name — the same component the ChatGPT and Uber chapters had, doing the same three jobs: authenticate, rate limit, route.

Worth noting only because of what it implies about the internal services: they trust their caller. The generation service does not re-authenticate; it assumes the gateway did. That is the standard trade — one enforcement point, and everything behind it is inside the trust boundary — and it means the gateway is security-critical in a way the diagram does not convey.

Key takeaway

Generation and publishing are separate services because they have different latency budgets — generation is expensive and asynchronous, publishing is cheap and sits inside the 2-second budget. Split components by latency budget, not subject matter. The notification service is really the fan-out trigger with push notifications bundled in, and those are two consumers of one POST_CREATED event rather than one service. And "appends a thumbnail and its link" is the reference model made concrete: deliver a cheap representation eagerly and the expensive one lazily, which is why media storage is per-object and media bandwidth is demand-driven.

Next: the API, and what its two calls reveal.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue