TweakCode
Worked Systems lessons

News Feed · Stage 1 of 3

Fanout-on-Read (Pull Model)

Build each reader's page at read time by merging followed sources

Foundations

A feed shows a reader the newest items from the sources they follow. In fanout-on-read, also called the pull model, nothing is prepared when a source publishes; each read fetches the recent items of every followed source and merges them, newest first, into one page. Publishing is a single write, and the page is always fresh.

The merge is the k-way merge from the Heap lessons: keep the front item of each source's sorted list in a heap, repeatedly take the newest, and stop when the page is full, never sorting everything. The cost is reads: every page view touches every followed source, so a reader following 500 sources pays 500 fetches per view.

Take three sources with items [x9, x4], [y8, y7], and [z6, z1], newest first. The merge compares the fronts x9, y8, and z6 and takes x9; then y8, then y7, then z6, filling a page of four without touching x4 or z1. That is three fetches here, and 500 for a heavy reader.

y8, y7x9, y8, y7, z6Source 1x9, x4Source 2Source 3z6, z1Mergenewest of frontsReaderpage of 4
Each page view fetches every followed source and merges their fronts until the page is full. It is always fresh, but a reader following 500 sources pays 500 fetches per view.
  • Requirements

    Each worked system starts from a scoped list of verbs and numbers.

    Open lesson
  • Queues

    Slow work leaves the request path through a queue.

    Open lesson

Case Scenario

The design brief

Design a text home timeline

Users post short text. Home shows the latest posts from accounts they follow, newest first, paged.

Input
posts = {"ana": [[9, "a9"], [4, "a4"]], "bo": [[8, "b8"], [7, "b7"]], "cy": [[6, "c6"], [1, "c1"]]}, following = ["ana", "bo", "cy"], limit = 4
Output
["a9", "b8", "b7", "c6"]

To see how fanout-on-read builds a feed, consider a text home timeline like X's: users post short text, and home shows the latest posts from accounts they follow, newest first, paged. Pull merges each followed account's recent posts on every home view: cheap to post and always fresh, but one read per followee every time.

Home must show the newest text posts from followed accounts, in stable pages. A reader may follow 500 accounts, and opening home is far more common than publishing, so work repeated on every open can dominate the system even when each merge is computationally small. The finished feed must make home a range read on one user’s timeline, not rebuild it from hundreds of account histories.

Pro

The rest of this is on Pro

The idea above is free. The walkthrough, the cost, and the practice are on Pro.