Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Got an interesting question today about 's outgoing design!

Some users noticed we create separate queue messages for each recipient inbox rather than queuing a single message and handling the splitting later. There's a good reason for this approach.

In the , server response times vary dramatically—some respond quickly, others slowly, and some might be temporarily down. If we processed deliveries in a single task, the entire batch would be held up by the slowest server in the group.

By creating individual queue items for each recipient:

  • Fast servers get messages delivered promptly
  • Slow servers don't delay delivery to others
  • Failed deliveries can be retried independently
  • Your UI remains responsive while deliveries happen in the background

It's a classic trade-off: we generate more queue messages, but gain better resilience and user experience in return.

This is particularly important in federated networks where server behavior is unpredictable and outside our control. We'd rather optimize for making sure your posts reach their destinations as quickly as possible!

What other aspects of Fedify's design would you like to hear about? Let us know!

A flowchart comparing two approaches to message queue design. The top half shows “Fedify's Current Approach” where a single sendActivity call creates separate messages for each recipient, which are individually queued and processed independently. This results in fast delivery to working recipients while slow servers only affect their own delivery. The bottom half shows an “Alternative Approach” where sendActivity creates a single message with multiple recipients, queued as one item, and processed sequentially. This results in all recipients waiting for each delivery to complete, with slow servers blocking everyone in the queue.
ALT text detailsA flowchart comparing two approaches to message queue design. The top half shows “Fedify's Current Approach” where a single sendActivity call creates separate messages for each recipient, which are individually queued and processed independently. This results in fast delivery to working recipients while slow servers only affect their own delivery. The bottom half shows an “Alternative Approach” where sendActivity creates a single message with multiple recipients, queued as one item, and processed sequentially. This results in all recipients waiting for each delivery to complete, with slow servers blocking everyone in the queue.
Julian Fietkau's avatar
Julian Fietkau

@julian@fietkau.social · Reply to Fedify: an ActivityPub server framework's post

@fedify Thanks for the explanation. 🙂 I have a related question that I've been meaning to ask:

If I give Fedify's sendActivity a list of recipients, does it do any deduplication or are activities sent twice if the same remote actor appears twice in my recipient list?

For example, a common addressing case is followers + tagged, and I've been wondering if I should check these for overlap myself or if I can leave it to Fedify. I couldn't find anything on this in the documentation.

julian's avatar
julian

@julian@community.nodebb.org · Reply to Fedify: an ActivityPub server framework's post

@fedify@hollo.social that's interesting! I didn't even consider that, but it makes a lot of sense.

Max's avatar
Max

@PossiblyMax@hachyderm.io · Reply to Fedify: an ActivityPub server framework's post

@fedify How many queues do you use? Is it based on any mathematical rules like number of users vs cpu cores, or memory requirements? Do you always spin up a new queue or cap the number and reuse the resources as they come available?