Guide

Fan-out is asynchronous, so followers see a new post at slightly different times. Deleted posts can also linger in timelines for a while. This page covers how the feed stays acceptable anyway: read-your-writes for an author's own posts, tombstones for deletes, filters for blocks and mutes, and backfill when someone follows.

The key idea is to avoid fixing every copy right away. Check at read time instead. A feed does not need perfect order across followers. It does need deleted posts, blocked users and an author's own posts to behave sensibly.

Walking through a new post

t=0      author A publishes post p_1
         A's own feed merges A's recent posts on read, so A sees p_1 at once
         fan-out workers start pushing p_1 to follower timelines
later    follower B's timeline gets p_1 first
later    follower C's timeline gets p_1 when the fan-out queue reaches C

That difference in order is fine for a feed. Stronger expectations, such as "I must see my own post immediately", are met with read-your-writes: on every feed load, merge the viewer's own recent posts from a small author cache.

Pagination follows the same rule. Encode (score, post_id) in the cursor, so a post that arrives mid-scroll doesn't silently reshuffle pages the user has already read.

Deletes and blocks

Fan-out copies post IDs into many timelines, so a delete or block can't reach every copy at once.

  • Delete: publish a PostDeleted event. Workers remove the ID from timelines that might hold it, or add it to a tombstone set (a record that the post is gone). The feed checks tombstones at hydration time. Checking at read is simpler and eventually correct.
  • Block or mute: filter at hydration or merge time, using a small per-user block set in the cache. Don't scrub every timeline synchronously. One user action would then write to millions of lists.

Follows and inactive users

When U follows A, write the follow edge, then run an async job that copies A's last N posts into U's timeline, if A is not a celebrity. For a celebrity, skip the backfill. U's next feed load merges A's recent posts anyway.

Pure push also wastes writes on inactive accounts. Cap the timeline TTL for inactive users, or keep push timelines only for users active in the last N days. Rebuild on return with a cold-start pull.

Common mistakes

  • Scrubbing every timeline on delete or block. One action becomes a flood of writes. Use tombstones and read-time filters.
  • Forgetting read-your-writes. An author who can't see their own post on refresh will report it as a bug.
  • Keeping push timelines for inactive users forever. Those writes are never read.

Check yourself

  1. Why not remove a deleted post from every follower's timeline right away?

    The post may sit in millions of lists, and writing to all of them synchronously is expensive. A tombstone checked at read time is simpler and becomes correct shortly after.

  2. Why does a celebrity skip the backfill when someone follows them?

    The new follower's next feed load merges the celebrity's recent posts anyway, so backfill would only copy them into the push timeline.

Key takeaways

  • Fan-out is asynchronous, so followers see posts at different times. That is acceptable.
  • Read-your-writes covers an author's own posts, merged on read.
  • Deletes use tombstones, and blocks use read-time filters. Neither scrubs every timeline.
  • Backfill copies recent posts on follow, skips celebrities, and inactive timelines should expire.

Further learning

Return to the news feed overview to see how all these pieces fit together.