Skip to main content
ExplainerActivityPub ProtocolFediverse· 6 min read· in Technology

Replacing Per-User HTTP Delivery With Shared Inboxes: How ActivityPub Compresses Fan-Out Across Federated Social Servers

The ActivityPub protocol uses a server-wide shared inbox to compress outbound network traffic, allowing decentralized platforms to distribute viral posts without overwhelming their own infrastructure.

By Tariq Nasser

In short

  1. The ActivityPub protocol uses a shared inbox mechanism to compress outbound network traffic, reducing the number of HTTP POST requests required for fan-out delivery.
  2. By grouping followers by their host server, an origin instance can send a single payload to a remote server, which then distributes the post to its local users.
  3. While highly efficient for public broadcasts, the shared inbox is generally bypassed for direct messages to maintain cryptographic privacy.

On January 23, 2018, the World Wide Web Consortium (W3C) published the ActivityPub specification, formalizing the protocol that now powers decentralized social networks. The standard defined a simple mechanism for servers to exchange messages. However, it also introduced a massive scaling problem for popular accounts.[1]

In a centralized network, a user with one million followers writes a post once, and a single database updates to serve it to everyone. In a federated network, servers must actively push that post to every individual follower. This process is known as fan-out delivery.[3]

Under the naive implementation of ActivityPub, an origin server must send a distinct HTTP POST request to the personal inbox of every single follower. If an account has 10,000 followers spread across various instances, the server must execute 10,000 separate outbound network requests.[1][2]

This creates a severe bottleneck. A sudden viral post can overwhelm the origin server's background workers, filling outbound message queues and consuming massive amounts of bandwidth. The network effectively launches a distributed denial-of-service attack against itself through normal operation.[2][5]

To prevent this architectural collapse, the W3C included an optional but critical optimization in Section 7.1.3 of the specification. This mechanism, known as the shared inbox, fundamentally alters how federated servers route public messages.[1]

How the shared inbox optimization shifts the routing burden to the receiving server.

The Architecture of the Shared Inbox

Every user on an ActivityPub network is represented by an Actor object, formatted as a JSON-LD document. This document contains cryptographic keys, profile metadata, and the URLs for the user's personal inbox and outbox.[1][3]

When a server supports optimized delivery, it adds a `sharedInbox` endpoint to this Actor document. This URL represents a single, server-wide collection point rather than a user-specific destination.[1]

The W3C specification states that a server "MAY reduce the number of receiving actors delivered to by identifying all followers which share the same sharedInbox." Instead of addressing users individually, the origin server groups them by their host instance.[1]

If 8,000 of a user's 10,000 followers reside on the Mastodon.social instance, the origin server skips the 8,000 personal inboxes. It sends exactly one HTTP POST request to the Mastodon.social shared inbox, containing the activity and its intended audience.[5]

The receiving server then assumes the routing burden. It parses the incoming 12-kilobyte JSON payload, checks the addressing fields, and inserts the post into the local timelines of the relevant 8,000 users.[2][4]

Mathematical Compression of Network Traffic

This shift in responsibility compresses outbound network traffic by orders of magnitude. The delivery complexity drops from a linear scale based on total followers to a scale based purely on the number of unique receiving servers.[5]

For highly concentrated networks, this optimization is the difference between a functional server and a crashed one. Sending a single payload once requires minimal resources, whereas sending it 8,000 times consumes nearly 100 megabytes of outbound bandwidth.[5]

Bandwidth consumption for a single post delivered to 8,000 users on a single remote server.

"For servers hosting many actors, delivery to all followers can result in an overwhelming number of messages sent," the W3C specification notes. The shared inbox was designed explicitly to serve this high-density use case.[1]

Frameworks like Fedify automatically implement this logic. When the fan-out process begins, the software scans the follower list, deduplicates the destination URLs by their shared inbox endpoints, and dispatches the consolidated payload.[2]

This efficiency relies entirely on the receiving server accurately processing the payload. If an origin server attempts to deliver to an inbox on a non-federated server, the W3C mandates it should receive a 405 Method Not Allowed response.[1]

Idempotency and Delivery Failures

Network requests frequently fail due to timeouts, server restarts, or DNS errors. ActivityPub servers must retry failed deliveries, which introduces the risk of duplicate messages arriving at a shared inbox.[2]

To handle this, the protocol relies on idempotency—the ability to process the same operation multiple times without changing the result. Every ActivityPub object carries a unique identifier formatted as a URL.[1][2]

When a shared inbox receives a payload, the server checks this identifier against its local database. If the identifier already exists, the server discards the duplicate request, preventing the same post from appearing twice in a user's feed.[2][4]

Different server implementations handle this deduplication at different layers. Some use a per-inbox strategy, tracking identifiers strictly within the shared endpoint, while others use a per-origin strategy to track activities across the entire receiving server.[2]

The reduction in outbound HTTP POST requests achieved by grouping followers by their host instance.

If a remote server is permanently offline, the origin server will eventually exhaust its retry attempts. The W3C specification recommends that servers perform delivery asynchronously and gracefully abandon unreachable endpoints after a set period.[1]

Privacy Constraints and Addressing

The shared inbox optimization is incredibly powerful, but it cannot be used for every type of message. Its utility is strictly limited by the privacy expectations of the payload being delivered.[4]

Public posts, addressed to the special W3C Public collection, are perfect candidates for shared delivery. The receiving server knows it can safely distribute the content to anyone who follows the author.[1][4]

However, direct messages and followers-only posts require stricter handling. If an activity is addressed only to specific individuals, sending it to a server-wide shared inbox exposes the private payload to the receiving server's administrators.[4]

While the W3C specification allows followers-only posts to utilize the shared inbox, many implementations avoid doing so for sensitive communications. True direct messages must always be routed to the recipient's personal inbox endpoint.[1][4]

This creates a bifurcated delivery system. Public broadcasts achieve massive network compression, while private communications remain unoptimized, trading bandwidth efficiency for cryptographic and architectural privacy.[5]

Illustration: Receiving servers act as local distribution hubs, parsing incoming payloads and routing them to individual user timelines.

The Foundation of the Fediverse

Without the shared inbox mechanism, the modern Fediverse could not exist at its current scale. While advocates often praise the ideological benefits of decentralization, the practical reality is that the network overhead of per-user delivery would bankrupt independent server operators.[3][5]

By standardizing this optimization, the W3C allowed decentralized networks to mimic the efficiency of centralized platforms. The origin server acts as a broadcaster, and the receiving servers act as local distribution hubs, solving a mathematical bottleneck rather than a philosophical one.[1][5]

This architecture mirrors the design of email, where a message sent to multiple employees at the same company is transmitted once to the corporate mail server, which then routes it to individual inboxes.[3]

As new platforms like Threads and Flipboard adopt ActivityPub, the density of users on single servers is increasing dramatically. A single shared inbox might now represent millions of potential recipients.[5]

The shared inbox remains one of the most elegant solutions in the ActivityPub specification. It proves that decentralized protocols can scale globally, provided they intelligently distribute the computational workload across the network.[1][5]

How we did this

Method
A mathematical comparison of HTTP POST request volumes required to distribute a single ActivityPub object to a distributed follower base, contrasting per-user inbox delivery against sharedInbox deduplication.
What we found
By shifting the routing burden from the origin server to the receiving server, the sharedInbox mechanism compresses outbound network traffic by a factor directly proportional to the density of followers on a given remote instance, transforming an O(N) network operation into an O(M) operation where M is the number of unique servers.
What we worked from
  • Per-user inbox delivery requirement: 1 HTTP POST per follower — W3C
  • Shared inbox delivery requirement: 1 HTTP POST per receiving server — W3C
Limits of this analysis
This analysis assumes all receiving servers support the optional sharedInbox endpoint and that the payload is a public broadcast; private messages still require O(N) delivery.

Key terms

ActivityPub
A decentralized social networking protocol standardized by the W3C that allows different servers to exchange messages.
Fan-out delivery
The process of distributing a single piece of content to a large number of individual followers across a network.
Actor object
A JSON-LD document representing a user or service on the network, containing their profile metadata and inbox URLs.
Idempotency
A property of network operations where applying the same action multiple times yields the same result as applying it once, preventing duplicate posts.
JSON-LD
A lightweight data format used by ActivityPub to structure and link data across different servers.

Frequently asked

What is a shared inbox in ActivityPub?

A shared inbox is a single, server-wide URL that accepts incoming messages on behalf of all users on that instance. It allows an origin server to deliver a post once, leaving the receiving server to distribute it to individual local users.

Does the shared inbox work for direct messages?

No. True direct messages must be sent to a user's personal inbox to ensure cryptographic privacy and prevent server administrators from easily intercepting restricted communications.

How much bandwidth does this optimization save?

The savings scale with the density of followers on a remote server. If 8,000 followers reside on one instance, the shared inbox reduces 8,000 HTTP POST requests down to exactly one, saving nearly 100 megabytes of outbound data for a standard JSON payload.

What happens if a shared inbox receives the same message twice?

ActivityPub servers use idempotency to handle duplicates. Every message has a unique URL identifier, and if the shared inbox sees an identifier it has already processed, it silently discards the duplicate.

Viewpoints in depth

Protocol Architects

Focuses on the necessity of the shared inbox for global scalability.

The engineers who drafted the ActivityPub specification view the shared inbox as the primary mechanism preventing the network from collapsing under its own weight. By shifting the computational burden of fan-out delivery to the receiving servers, they ensured that independent, low-resource instances could still participate in global conversations without being bankrupted by outbound bandwidth costs.

Privacy Advocates

Raises concerns about exposing payload metadata to server administrators.

Privacy-focused developers argue that while the shared inbox is highly efficient for public broadcasts, it introduces risks for restricted content. Sending a followers-only post to a server-wide endpoint means the receiving server's administrators can theoretically inspect the payload before it reaches the intended recipients, leading some implementations to bypass the optimization for anything short of a fully public message.

Instance Operators

Values the reduction in queue backups and server load.

For the administrators actually running Fediverse servers, the shared inbox is a critical operational lifeline. Without it, a single viral post from a local user could spawn tens of thousands of background jobs, locking up the server's database and delaying all other network traffic until the queue clears.

Protocol Architects 40%Privacy Advocates 30%Instance Operators 30%
Protocol Architects
Focuses on the necessity of the shared inbox for global scalability and network survival.
Privacy Advocates
Raises concerns about exposing payload metadata to server administrators during restricted broadcasts.
Instance Operators
Values the reduction in queue backups, server load, and exorbitant bandwidth costs.

Perspectives this story doesn't cover

  • End Users

Sources

Source coverage

5 outlets

3 viewpoints surfaced

Protocol Architects 40%Privacy Advocates 30%Instance Operators 30%
  1. [1]W3CProtocol Architects

    ActivityPub

    Read on W3C →
  2. [2]FedifyInstance Operators

    Sending activities

    Read on Fedify →
  3. [3]Mozilla HacksProtocol Architects

    Decentralizing Social Interactions with ActivityPub

    Read on Mozilla Hacks →
  4. [4]GitHubPrivacy Advocates

    Mastodon Issue: Un-deliver a status

    Read on GitHub →
  5. [5]Factlen Editorial TeamInstance Operators

    Synthesis by Factlen editorial team

    Read on Factlen Editorial Team →

Comments

Stay informed

Every angle. Every day.

Get Technology stories with full source coverage and perspective breakdowns, free every day.