Putting It Together
In one line: assembled, the architecture shows something none of the component lessons state: three separate caches, each solving a different problem, and the design does not work without any of them.
The full picture
Three caches, three different jobs — and the design collapses without any of them
The diagram shows a user cache, a post cache, and a newsfeed cache. They look like generic performance layers. They are not — each solves a distinct structural problem.
| Cache | Holds | Solves |
|---|---|---|
| User cache | Names, avatars, profile data | Hydration fan-out — one feed touches 20 distinct authors |
| Post cache | Post text and metadata | Extreme read skew — the same popular post is in millions of feeds |
| Newsfeed cache | <Post_ID, User_ID> ranked lists | The materialized view itself |
The third is not a cache at all in the ordinary sense, and that is the important observation.
A conventional cache holds a copy of data that exists elsewhere, so a miss costs a slower read of the same bytes. The user and post caches are exactly that.
The newsfeed cache holds the result of an expensive computation — a graph traversal, a candidate fetch, and a ranking pass over thousands of features. A miss does not cost a slower read; it costs regenerating the feed.
That is the same distinction that building block drew about semantic caching: when the cached item is expensive to produce rather than merely slow to fetch, every caching rule changes. Hit rates that would embarrass a web cache are valuable, and eviction is a product decision rather than a memory one — evicting an active user's feed means recomputing it.
Which is why the diagram also shows a newsfeed database behind the cache. The materialized feed is durable, not merely cached — losing it would mean a ranking storm.
Follow the two paths and the architecture separates cleanly
WRITE PATH (asynchronous, expensive)
Bob posts -> post service -> post DB + post cache + blob store
-> notification service -> newsfeed service
-> graph DB (who follows Bob?) -> ranking -> newsfeed cache
READ PATH (synchronous, under 2 seconds)
Alice opens app -> web server -> newsfeed cache (already ranked)
-> publishing service -> hydrate from post + user caches
-> media thumbnails + links -> client
Almost nothing is shared. The write path touches the graph database and the ranking service; the read path touches neither.
That separation is what makes Lesson 2's requirement achievable — "complex feed generation can run asynchronously, but the read path must remain fast." The newsfeed cache is the seam, and everything expensive is on its far side.
When a requirement says one path must be fast and another may be slow, the design is a materialized view and the cache between them is the architecture. Name the seam and the rest follows.
The monitoring service appears only in the final diagram
Worth noticing: monitoring is absent from the component list, absent from the high-level design, and appears only in the assembled diagram and one line of Lesson 12's evaluation.
That ordering is backwards, and it matters more here than in most designs, for a reason specific to ranked feeds.
In a conventional system, monitoring answers "is it up and is it fast?" — and metrics like error rate and latency suffice. In a ranked feed, the system can be perfectly healthy and producing a bad feed:
- The ranking model degrades and nobody's dashboards move.
- A retrieval bug silently drops a class of candidates.
- Engagement falls for reasons no infrastructure metric captures.
So this design needs two kinds of observability: infrastructure health, which the monitoring service provides, and feed quality, which nothing here addresses — no A/B framework, no offline evaluation, no counterfactual logging.
That is the same gap that building block identified: the evaluation of output quality is absent from a system whose entire value is output quality. Worth raising unprompted.
Where the media path sits, and why it barely touches the feed
Trace media through the diagram and it is strikingly disconnected:
Upload: post service -> blob storage Serve: blob storage -> CDN -> client Feed: thumbnail + LINK only
The feed pipeline never carries the bytes. It carries a thumbnail for rendering the list and a link the client follows on demand.
Three consequences, all established earlier and worth collecting:
Storage is per-object. Lesson 3's 56 PB double-count comes from ignoring this.
Bandwidth is demand-driven. You pay egress for media people actually open, not for everything scrolled past.
The CDN serves components, not feeds. Lesson 9's point — media and popular posts cache well at the edge; the personalized feed cannot.
The most expensive data in the system is deliberately routed around the most complex part of the system. That is a good design instinct generally: keep bulk bytes out of pipelines that do per-user work.
Key takeaway
Three caches, three problems: user cache for hydration fan-out, post cache for extreme read skew, and the newsfeed cache, which is not a cache at all but a materialized view — a miss costs regeneration rather than a slower read, which changes every caching rule and is why a durable newsfeed database sits behind it. The write and read paths share almost nothing, and the newsfeed cache is the seam that keeps expensive work out of the 2-second budget. Monitoring appears only in the final diagram, and the deeper gap is that a ranked feed can be perfectly healthy while producing bad output — feed quality has no observability here at all. And media is deliberately routed around the feed pipeline, carrying only thumbnails and links.
Next: checking the design against its requirements.