---
id: "push-fanout-without-celebrity-path"
type: "rule"
severity: "warning"
url: "https://localhost:3000/catalogue/rules/push-fanout-without-celebrity-path"
---

# Push fan-out without a celebrity threshold

A worker pushes fan-out over a social graph with no follower threshold above which timelines are merged at read time.

| | |
|---|---|
| Severity | warning |
| Selects | every node of kind worker |
| Components in scope | 83 |

## Why

Pure push fan-out over a social graph is brutal at the tail: one post from an account with millions of followers becomes millions of cache writes. A follower threshold above which readers merge at read time bounds that write amplification.

## What it checks

It looks at every node of kind worker, and fires when:

- all of these hold:
  - the node's `fanoutStrategy` is "push"
  - the node's `fanoutThreshold` has no value
  - the design contains a node of kind graph-database

Message template:

```
Worker '{{node.id}}' pushes fan-out over a social graph with no fanoutThreshold. Declare a follower threshold above which timelines are merged at read time.
```

## Applies to

- [Worker](https://localhost:3000/catalogue/kinds/worker.md) `worker`

83 catalogue components fall under it.

## Tripped by

Reference designs whose broken twin names this rule in its header:

- [meta-threads](https://localhost:3000/d/zeema/meta-threads)
- [twitter-timeline](https://localhost:3000/d/zeema/twitter-timeline)

## Source (`rule` YAML, verbatim)

```yaml
# yaml-language-server: $schema=../schema/rule.schema.json
# Pure push fan-out over a social graph is brutal at the tail: one post by an account with
# millions of followers becomes millions of cache writes. A threshold above which the worker
# stops pushing and readers merge at read time bounds that write amplification.
# Tripped by: designs/twitter-timeline.broken.yaml
schemaVersion: "1"
type: "rule"
id: "push-fanout-without-celebrity-path"
severity: "warning"
select:
  node:
    kind: "worker"
when:
  all:
    - prop: "fanoutStrategy"
      equals: "push"
    - prop: "fanoutThreshold"
      exists: false
    - hasNode:
        kind: "graph-database"
message: "Worker '{{node.id}}' pushes fan-out over a social graph with no fanoutThreshold. Declare a follower threshold above which timelines are merged at read time."
```

Human page: https://localhost:3000/catalogue/rules/push-fanout-without-celebrity-path
