#DevOps

System Design: Social Media Feeds (WeChat Moments, Twitter, and Weibo)

Feed systems are a demanding design problem: high read and write volume, ranking, real-time delivery, and scalability. This article explains push, pull, and hybrid models; timeline storage; popular content; pagination and end-of-feed behavior; and what to choose at tens of thousands versus hundreds of millions of users.

Key Points

  • Topic Focus: DevOps
  • Suitable for: indie hackers, full-stack engineers, AI application developers
  • Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
Author @admin·Published July 26, 2026·Updated July 26, 2026

System Design: Social Media Feeds (WeChat Moments/Twitter/Weibo)

1. What Problem Does a Feed Actually Solve?

Open Weibo, Twitter, or WeChat Moments, and the home screen presents a stream of content ordered by time or interest. That is a Feed. It looks like a simple list, but the system behind it is a serious engineering challenge.

Its central tension is this: high read and write volume, plus ranking, real-time delivery, and scalability. In an ordinary social product, a user may publish only a few posts per day but refresh the Feed dozens of times and read dozens of items each time. The read/write ratio is naturally skewed heavily toward reads. Yet writes cannot be underestimated: a single high-follower account may need to deliver one post to tens of millions of followers, instantly turning write fan-out into a disaster.

Break the requirements down:

  • Follow relationships: Who follows whom forms a directed graph. If A follows B, that does not mean B follows A.
  • Timeline ordering: By default, the Feed is sorted in reverse chronological order, with the newest content first.
  • Real-time delivery: Ideally, a follower can see a new post within seconds of its publication.
  • High read and write volume: Refreshes far outnumber posts, but each publication can create enormous instantaneous load.
  • Scalability: The system must not require a complete rewrite when the user base grows from ten thousand to one hundred million.

These five requirements pull against one another. You want both real-time delivery and fast reads, but the more work you precompute to accelerate reads, the more expensive writes become. Designing a Feed system is fundamentally an exercise in repeatedly balancing reads against writes and real-time delivery against scalability.

2. Push Model (Fan-Out on Write): Finish the Work When Publishing

The most intuitive approach is to prepare every follower's Feed during the write.

When publisher B creates a post, the system immediately finds all of B's followers and writes the post ID into each follower's "inbox." When follower A refreshes the Feed, the system reads A's inbox directly and returns the result with a single query.

text
B 发帖 → 查粉丝列表 [A, C, D, E...] → 写入 A.inbox / C.inbox / D.inbox ...
A 刷 Feed → 直接读 A.inbox(已排好序)
  • Advantages: Reads are extremely fast, retrieving prepared results in O(1); the read path is simple and easy to cache.
  • Disadvantages: Write amplification is severe. One post from an account with one million followers requires one million writes, and if those followers are offline at the time, all those writes are wasted.

The high-follower account disaster is unavoidable in the push model. Imagine a celebrity with 50 million followers posting "Good morning." The system must synchronously fan out 50 million times. At best, latency spikes and queues accumulate; at worst, both the cache and database go down.

The push model is therefore suitable for scenarios with a small user base and generally modest follower counts, such as an internal enterprise social network or a small community. It works well as the default solution, but once top-tier accounts appear, the system must be ready to switch gears.

3. Pull Model (Fan-Out on Read): Compute the Feed at Read Time

Consider the opposite approach: do nothing during the write and fetch everything on demand during the read.

When B publishes a post, the system writes it only to B's "outbox." When A refreshes the Feed, the system first looks up everyone A follows, pulls the latest N items from each person's outbox, then merges, sorts, deduplicates, and returns them to A.

text
B 发帖 → 只写 B.outbox
A 刷 Feed → 查关注列表 [B, C, D] → 各拉最新 20 条 → 归并排序
  • Advantages: The write path is O(1), so a post from a high-follower account costs the same as anyone else's. There is no write amplification, and storage consumption is lower.
  • Disadvantages: The read path is extremely expensive. Following 500 people means querying 500 outboxes. Even if every query hits the cache, merging and sorting still consume CPU, while read latency undermines real-time delivery.

Following too many accounts makes everything slow, which is the pull model's fatal weakness. A heavy user following 2,000 people requires the system to search through 2,000 outboxes on every Feed refresh, making the experience unusable.

The pull model is therefore suitable when users generally follow few accounts and read QPS is manageable, or as a dedicated fallback for high-follower accounts. Note that the pull model depends heavily on caching. Once the cache hit rate drops, P99 latency soars.

4. Combining Push and Pull: The Classic Engineering Solution

The push model struggles with high-follower accounts, while the pull model struggles with users who follow many accounts. The solution is to handle those cases separately:

  • Posts from ordinary users → push model: They have relatively few followers, so fan-out costs remain manageable and reads stay fast.
  • Posts from high-follower accounts → pull model: Do not fan out. Write only to the outbox and let followers pull the content when reading.

How should a "high-follower account" be defined? A common approach is to set a follower-count threshold, such as 10,000 or 100,000, and classify any account above it accordingly. The threshold can be adjusted dynamically. When a follower refreshes the Feed, the system first gets content pushed into the follower's inbox by ordinary accounts, then pulls the latest items from the outboxes of followed high-follower accounts, merges everything, and returns the result.

text
A 刷 Feed:
  1. 读 A.inbox(普通关注人的推送)
  2. 对 A 关注的大 V,逐个拉最新 N 条
  3. 合并、去重、排序
  4. 返回

This is the classic approach used by early Twitter and Weibo, and a push-pull hybrid is sufficient for 80% of engineering scenarios. It is not theoretically optimal, but it offers the best engineering cost-benefit ratio. Do not let the "push versus pull" dichotomy mislead you; real systems are almost always hybrids.

5. Storage: Inboxes, Outboxes, and Follow Relationships

A Feed system has three core storage components:

  • Outbox: One per user, containing the IDs and timestamps of posts published by that user. It is naturally an append-only stream ordered by time.
  • Inbox (user timeline): One per user, containing the IDs of posts that "should be shown to this person." It is populated by the push model and not stored by the pull model.
  • Follow relationship (follow edge): A directed follower → followee edge. The system must support both directions: finding B's followers for pushing and finding everyone A follows for pulling.

In practice, common implementation choices are:

  • Redis ZSet, scored by timestamp, or List is most commonly used for outboxes and inboxes. If sufficient memory is available, either is fast enough.
  • A relational database can support follow relationships for a while. At larger scales, move to a graph database or dedicated graph store.
  • Store post bodies separately in a KV or document database. Keeping only IDs in the Feed is an iron rule. Putting full post bodies in a ZSet consumes excessive space and makes updates difficult.

One commonly overlooked detail is that inboxes cannot grow indefinitely. They usually have a fixed limit, such as the latest 1,000 items, after which older data is evicted. Most users never scroll that far, and the memory savings are worth far more than theoretical completeness.

6. Ranking Beyond the Timeline

The simplest Feed uses reverse chronological order, but modern products almost always introduce recommendation or popularity ranking:

  • Chronological order: Simple to implement, but content quality varies and low-value posts surface easily. Fewer and fewer products use a purely chronological Feed.
  • Popularity/recommendation order: Requires an independent ranking service that considers likes, comments, reposts, time decay, user interests, and other signals to produce a score. This is the recommendation system's job.

A common layered implementation is to use the timeline first to preserve real-time delivery, showing the newest few items chronologically, and then use the recommendation service to rerank subsequent content. Instagram is a representative example of a nearly chronological Feed, while Twitter, Weibo, and Douyin all use algorithmic reranking.

The ranking service usually operates asynchronously. After a user publishes a post, followers first see it immediately in chronological order. The ranking service then calculates scores offline and backfills them. Do not let ranking block the write path, or real-time delivery will collapse. If the ranking service goes down, the Feed should degrade gracefully to chronological order instead of returning a 500 error.

7. Pagination: Why Cursors Are Better Than Offsets

A Feed must be paginated, but traditional pagination such as LIMIT 20 OFFSET 1000 is an anti-pattern for Feeds:

  • The larger the offset becomes, the more rows the database must scan and skip, making deep pagination extremely slow.
  • A Feed is dynamic. By the time a user opens the second page, new posts may have entered the first page, causing offsets to shift and producing duplicates or omissions.

The correct approach is cursor pagination: use the final item's (时间戳, 帖子 ID) from the previous page as the cursor, then query the next page with WHERE (ts, id) < (cursor_ts, cursor_id) LIMIT 20.

  • Index performance remains stable and does not deteriorate with depth.
  • New inserts do not cause shifts, duplicates, or omissions.

The challenge of "reaching the end" is that many Feeds are designed to continue loading indefinitely; a Weibo home Feed can be refreshed all day. In practice, either limit the maximum depth and display "You have reached the end" after N pages, or use a hybrid strategy: serve recent content from the inbox and supplement deeper pages through the recommendation service. A truly infinite scroll is extremely difficult to implement in a distributed system because an inbox has finite physical capacity and deeper pagination eventually requires switching data sources.

8. Choosing an Architecture for Each Scale

Do not begin with a push-pull hybrid, recommendation system, and distributed timeline. Scale determines the architecture, and overengineering is more expensive than insufficient design:

  • Small scale (tens of thousands of users, dozens of follows per user): Use a pure push model. Redis ZSet serves as the inbox. It is simple, direct, and fast for both reads and writes. An intern can ship it in a week.
  • Medium scale (hundreds of thousands to several million users, with high-follower accounts): Combine push and pull. Set a follower-count threshold, use pull for high-follower accounts, and push for ordinary users. This is the highest-value transition point.
  • Large scale (hundreds of millions of users and hundreds of thousands of read QPS): Use a distributed timeline service and an independent recommendation system. Shard inboxes by user across multiple Redis clusters, move ranking into a dedicated Ranking Service, and use Kafka for asynchronous fan-out. At this stage, "push or pull" has become an implementation detail. The real challenge is the three-way tradeoff among cost, latency, and consistency.

9. Real-World Cases: The Evolution of Twitter and Weibo

Twitter is a textbook case in Feed system design. It initially used a pure push model and materialized every user's timeline in Redis. As the user base grew, however, fan-out costs for high-follower accounts exploded. Reportedly, a single Bieber tweet triggered hundreds of thousands of writes. Twitter gradually moved toward a hybrid architecture, using recommendation-based reranking for its core timeline, or algorithmic Feed, while introducing pull as a fallback for high-follower accounts. The evolution of its fanout service, documented on Twitter's engineering blog, is essential reading.

Weibo faced an even harder problem: high-follower accounts in Chinese social media, including celebrities and official accounts, can easily have hundreds of millions of followers, making a pure push model completely impractical. Weibo adopted a push-pull hybrid early. High-follower accounts write only to their outboxes, while followers pull their content according to weight. It later introduced large-scale machine-learning recommendation and ranking, and the home Feed has long since moved beyond simple chronological ordering. Weibo's engineering blog contains extensive practical experience with "inbox sharding" and "dynamic follower-threshold adjustment" that is worth studying closely.

The two cases share one lesson: scale forced both architectures to evolve. Neither company designed a perfect Feed system on day one. A good architecture is not complete from the beginning; it leaves room to evolve.

Summary

  • The central tension in a Feed is high read and write volume plus real-time delivery and ranking. Every solution trades reads against writes.
  • The push model has fast reads and slow writes, and struggles with high-follower accounts. The pull model has fast writes and slow reads, and struggles when users follow many accounts. A push-pull hybrid offers the best value in 80% of scenarios.
  • The three essential storage components are outboxes, inboxes, and follow relationships. Store only IDs in the Feed and keep post bodies separately.
  • Always use cursor pagination; offsets are an anti-pattern. An "infinite scroll" is extremely difficult in a distributed system and requires the recommendation service as a fallback.
  • Scale determines the architecture: use push at small scale, a push-pull hybrid at medium scale, and a distributed timeline plus recommendation system only at very large scale.

Key takeaway: Feed systems have no silver bullet, only compromises appropriate to their scale. The push-pull debate is fundamentally about moving write costs to reads or read costs to writes, and your user count determines which side you can better afford.

Related

Related Content