TweakCode
Worked Systems lessons

News Feed · Stage 2 of 3

Fanout-on-Write (Push Model)

Copy each new item into every follower's timeline so home is one read

Foundations

In the first lesson, every page view repeated the merge. Now, what if reads vastly outnumber writes, so it is cheaper to do the work once, when an item is published?

In fanout-on-write, the push model, publishing an item enqueues a job; a worker looks up the publisher's followers and prepends the item's id to each follower's precomputed timeline, trimming it to a fixed length. A read is then one range read of the reader's own timeline. Writes cost one insert per follower, done in the background, and an insert keyed by (reader, item) makes retries harmless.

Take a publisher with 200 followers. One publish costs 1 durable write plus 200 background timeline inserts; each follower's page view is then 1 read, however many sources they follow. A follower who opens home before the worker reaches them sees the previous page, within the freshness window.

1 writeprepend1 readPublisherQueueWorker200 insertsTimelinesone per readerReader
Publishing costs one write plus 200 background inserts, so each reader's home becomes a single read of their own timeline.
  • Queues

    Slow work leaves the request path through a queue.

    Open lesson

Case Scenario

The design brief

Design fanout for a normal post

A user with 200 followers posts. Home for those followers should include it within a few seconds. The post call should return quickly.

Input
followers = {"ana": ["bo", "cy"], "bo": ["cy"]}, cap = 3
Output
{"bo": [[3, "ana: again"], [1, "ana: hello"]], "cy": [[3, "ana: again"], [2, "bo: hi"], [1, "ana: hello"]]}

To see how fanout-on-write makes reads cheap, consider a news feed like Instagram's: a user with 200 followers posts, those followers' home timelines should include it within a few seconds, and the post call should return quickly. A worker prepends the post to 200 timelines after the post commits, so home is one read.

A normal author has about 200 followers, and each follower expects the post in home within a few seconds. Updating all 200 homes before replying makes author latency depend on follower count, while doing no preparation makes every reader repeat the merge. The post call must return after one durable write, without waiting for 200 timeline updates.

Pro

The rest of this is on Pro

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