Before the diagrams
Requirements & Data Flow
What the system has to do, what it has to be, and the sequence of steps that connects the two — written down once so every subsystem in this guide can be judged against the same bar.
Functional Requirements
Core Requirements
- Users can post a tweet, which becomes visible to their followers.
- Users can view a home timeline composed of tweets from the people they follow.
- Users can follow and unfollow other users.
Below the line (out of scope)
- Direct messages — a different read/write and encryption model entirely.
- Ads & monetization — an orthogonal ranking and billing system.
- Spaces / live media — real-time streaming, not a feed problem.
- Payments, video transcoding, multi-region writes — worth naming as real, but follow-ups, not a first pass.
Non-Functional Requirements
Before locking in non-functional requirements, it's worth sizing the system out loud, because scale is what decides the fan-out and timeline architecture here. Say there are 500 million monthly active users and 200 million daily active users, posting 500 million tweets a day — roughly 6,000 writes/sec on average. Reads dwarf that: with a read:write ratio of several orders of magnitude, home-timeline requests run into the hundreds of thousands per second at peak. That asymmetry — writes are rare, reads are relentless — is what justifies precomputing and caching timelines before anything else does.
Core Requirements
- Highly available — a slightly stale timeline is fine; a feed that's down is not.
- Low-latency timeline reads (sub-second), since this is the endpoint users hit dozens of times a day.
- Eventually consistent fan-out — a few seconds' delay before a tweet reaches every follower's feed is acceptable.
- Durable tweet storage — a posted tweet must never be lost once accepted.
- Scalable to a highly skewed follower distribution (the celebrity-account fan-out problem).
Below the line (out of scope)
- Strict read-after-write consistency across every follower's feed instantly.
- Exactly-once fan-out delivery guarantees beyond idempotent retries.
- Multi-region active-active writes.
Data Flow
- A user composes and submits a tweet.
- The tweet is ingested, validated, and durably stored.
- The tweet is fanned out — pushed to followers' precomputed timelines, or left for on-demand pull if the author has an unusually large follower count.
- A follower requests their home timeline; the system serves the precomputed feed or merges it with pulled content.
- Follow/unfollow actions update the follow graph, changing future fan-out targets.
High-Level Design
With requirements set, sketch the minimal set of components that satisfy them, wired directly to the endpoints above — not a generic "backend" box.
Click a component to see its role in this flow.
1. Posting a Tweet — POST /api/tweets
Client → Load Balancer → Tweet Service, which validates the tweet and durably writes it to the Tweet DB, then returns immediately — fan-out happens off the request path. It publishes the new tweet onto a Fan-out Queue; a Fan-out Worker consumes it, looks up the author's followers via the Follow Service, and pushes the tweet's ID into each follower's precomputed entry in the Timeline Cache. Tweet Ingestion → Timeline Generation →
2. Viewing a Home Timeline — GET /api/timeline
Client → Load Balancer → Timeline Service, which reads the requesting user's precomputed list of tweet IDs from the Timeline Cache, hydrates the actual tweet content from the Tweet DB, and returns the assembled feed. Timeline Generation →
3. Following a User — POST /api/users/{id}/follow
Client → Load Balancer → Follow Service, which writes a new edge into the Follow Graph DB. This doesn't affect any tweets already posted, but changes which timelines that account's future tweets fan out to. Follow Graph →