Fedify: ActivityPub server framework's avatar

Fedify: ActivityPub server framework

@fedify@hollo.social

9 following1,147 followers

:fedify: Fedify is a TypeScript library for building federated server apps powered by ActivityPub and other standards, so-called fediverse. It aims to eliminate the complexity and redundant boilerplate code when building a federated server app, so that you can focus on your business logic and user experience.

Pinned

🎉 Excited to announce that is now on Open Collective! Support the project's development starting at:

  • Backer (from $5/mo)
  • Supporter (from $25/mo)
  • Sponsor (from $100/mo)
  • Corporate Sponsor (from $500/mo)
  • Custom donations welcome

Your support will help us maintain and improve Fedify. Check it out here:

https://opencollective.com/fedify

:fedify:

Fedify's Open Collective page showing the project logo, description as “A TypeScript library for building federated server apps powered by ActivityPub and other standards”, and five contribution tiers starting from $5/month Backer to $500/month Corporate Sponsor, with custom contribution options available.
ALT text

Fedify's Open Collective page showing the project logo, description as “A TypeScript library for building federated server apps powered by ActivityPub and other standards”, and five contribution tiers starting from $5/month Backer to $500/month Corporate Sponsor, with custom contribution options available.

Pinned

Fedify is an server framework in & . It aims to eliminate the complexity and redundant boilerplate code when building a federated server app, so that you can focus on your business logic and user experience.

The key features it provides currently are:

If you're curious, take a look at the website! There's comprehensive docs, a demo, a tutorial, example code, and more:

https://fedify.dev/

Excited to see the ( Linux Users Group) in organizing a reading club for our Creating your own federated microblog tutorial! 🎉 Their first session is coming up, where participants will work through creating their own -compatible microblog using . Thanks for spreading the word about Fedify in Japan! :fedify: 🇯🇵

Check out their event on Connpass!

https://msky.ospn.jp/notes/a5re87hzi7s80062

msky.ospn.jp

Fediverse Linux Users Group (@fedilug)

【輪読会試験開催のお知らせ】 本日、 #FediLUG :fedilug: 輪読会📖第0弾として 「〜自分でActivityPub対応SNSを作ってみよう〜『自分だけのフェディバースのマイクロブログを作ろう!』輪読会」 https://github.com/dahlia/fedify-microblog-tutorial-ja を行います!申し込みは以下からできます!ぜひ参加してフィードバックをください!! https://fedilug.connpass.com/event/348240/

Excited to see the ( Linux Users Group) in organizing a reading club for our Creating your own federated microblog tutorial! 🎉 Their first session is coming up, where participants will work through creating their own -compatible microblog using . Thanks for spreading the word about Fedify in Japan! :fedify: 🇯🇵

Check out their event on Connpass!

https://msky.ospn.jp/notes/a5re87hzi7s80062

msky.ospn.jp

Fediverse Linux Users Group (@fedilug)

【輪読会試験開催のお知らせ】 本日、 #FediLUG :fedilug: 輪読会📖第0弾として 「〜自分でActivityPub対応SNSを作ってみよう〜『自分だけのフェディバースのマイクロブログを作ろう!』輪読会」 https://github.com/dahlia/fedify-microblog-tutorial-ja を行います!申し込みは以下からできます!ぜひ参加してフィードバックをください!! https://fedilug.connpass.com/event/348240/

@fedilug@msky.ospn.jp
@liaizon@wake.st
@fedify@hollo.social · Reply to silverpill

@silverpill You've touched on a good point. Since Fedify abstracts the message queue, the performance characteristics depend on the backend you're using (Redis, PostgreSQL, AMQP, etc.). Some backends might support batch operations, but we need to maintain compatibility with all supported queue implementations, which often means separate write operations.

Your concern about sequential processing is valid. Our new approach actually addresses this by maintaining individual recipient messages in the second stage, so slow servers don't block others.

What we've found is that maintaining the (activity, single recipient) pattern in the final queue gives you the best of both worlds: fast API responses via the fan-out queue, plus independent delivery processing. This way, a slow server only affects its own delivery task.

@fedify@hollo.social · Reply to silverpill

@silverpill The bottleneck happens because for each recipient, we need to:

  1. Serialize the activity data
  2. Create a queue message with metadata
  3. Write to queue storage

When you have thousands of followers, these operations add up quickly and block the HTTP response. With fan-out, we only do this once during the request.

What issues are you having with your current fan-out implementation? We're always looking to improve ours.

Coming soon in 1.5.0: Smart fan-out for efficient activity delivery!

After getting feedback about our queue design, we're excited to introduce a significant improvement for accounts with large follower counts.

As we discussed in our previous post, Fedify currently creates separate queue messages for each recipient. While this approach offers excellent reliability and individual retry capabilities, it causes performance issues when sending activities to thousands of followers.

Our solution? A new two-stage “fan-out” approach:

  1. When you call Context.sendActivity(), we'll now enqueue just one consolidated message containing your activity payload and recipient list
  2. A background worker then processes this message and re-enqueues individual delivery tasks

The benefits are substantial:

  • Context.sendActivity() returns almost instantly, even for massive follower counts
  • Memory usage is dramatically reduced by avoiding payload duplication
  • UI responsiveness improves since web requests complete quickly
  • The same reliability for individual deliveries is maintained

For developers with specific needs, we're adding a fanout option with three settings:

  • "auto" (default): Uses fanout for large recipient lists, direct delivery for small ones
  • "skip": Bypasses fanout when you need different payload per recipient
  • "force": Always uses fanout even with few recipients
// Example with custom fanout setting
await ctx.sendActivity(
  { identifier: "alice" },
  recipients,
  activity,
  { fanout: "skip" }  // Directly enqueues individual messages
);

This change represents months of performance testing and should make Fedify work beautifully even for extremely popular accounts!

For more details, check out our docs.

What other optimizations would you like to see in future Fedify releases?

Flowchart comparing Fedify's current approach versus the new fan-out approach for activity delivery.

The current approach shows:

1. sendActivity calls create separate messages for each recipient (marked as a response time bottleneck)
2. These individual messages are queued in outbox
3. Messages are processed independently
4. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server)

The fan-out approach shows:

1. sendActivity creates a single message with multiple recipients
2. This single message is queued in fan-out queue (marked as providing quick response)
3. A background worker processes the fan-out message
4. The worker re-enqueues individual messages in outbox
5. These are then processed independently
6. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server)

The diagram highlights how the fan-out approach moves the heavy processing out of the response path, providing faster API response times while maintaining the same delivery characteristics.
ALT text

Flowchart comparing Fedify's current approach versus the new fan-out approach for activity delivery. The current approach shows: 1. sendActivity calls create separate messages for each recipient (marked as a response time bottleneck) 2. These individual messages are queued in outbox 3. Messages are processed independently 4. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server) The fan-out approach shows: 1. sendActivity creates a single message with multiple recipients 2. This single message is queued in fan-out queue (marked as providing quick response) 3. A background worker processes the fan-out message 4. The worker re-enqueues individual messages in outbox 5. These are then processed independently 6. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server) The diagram highlights how the fan-out approach moves the heavy processing out of the response path, providing faster API response times while maintaining the same delivery characteristics.

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

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.

Coming soon in 1.5.0: Smart fan-out for efficient activity delivery!

After getting feedback about our queue design, we're excited to introduce a significant improvement for accounts with large follower counts.

As we discussed in our previous post, Fedify currently creates separate queue messages for each recipient. While this approach offers excellent reliability and individual retry capabilities, it causes performance issues when sending activities to thousands of followers.

Our solution? A new two-stage “fan-out” approach:

  1. When you call Context.sendActivity(), we'll now enqueue just one consolidated message containing your activity payload and recipient list
  2. A background worker then processes this message and re-enqueues individual delivery tasks

The benefits are substantial:

  • Context.sendActivity() returns almost instantly, even for massive follower counts
  • Memory usage is dramatically reduced by avoiding payload duplication
  • UI responsiveness improves since web requests complete quickly
  • The same reliability for individual deliveries is maintained

For developers with specific needs, we're adding a fanout option with three settings:

  • "auto" (default): Uses fanout for large recipient lists, direct delivery for small ones
  • "skip": Bypasses fanout when you need different payload per recipient
  • "force": Always uses fanout even with few recipients
// Example with custom fanout setting
await ctx.sendActivity(
  { identifier: "alice" },
  recipients,
  activity,
  { fanout: "skip" }  // Directly enqueues individual messages
);

This change represents months of performance testing and should make Fedify work beautifully even for extremely popular accounts!

For more details, check out our docs.

What other optimizations would you like to see in future Fedify releases?

Flowchart comparing Fedify's current approach versus the new fan-out approach for activity delivery.

The current approach shows:

1. sendActivity calls create separate messages for each recipient (marked as a response time bottleneck)
2. These individual messages are queued in outbox
3. Messages are processed independently
4. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server)

The fan-out approach shows:

1. sendActivity creates a single message with multiple recipients
2. This single message is queued in fan-out queue (marked as providing quick response)
3. A background worker processes the fan-out message
4. The worker re-enqueues individual messages in outbox
5. These are then processed independently
6. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server)

The diagram highlights how the fan-out approach moves the heavy processing out of the response path, providing faster API response times while maintaining the same delivery characteristics.
ALT text

Flowchart comparing Fedify's current approach versus the new fan-out approach for activity delivery. The current approach shows: 1. sendActivity calls create separate messages for each recipient (marked as a response time bottleneck) 2. These individual messages are queued in outbox 3. Messages are processed independently 4. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server) The fan-out approach shows: 1. sendActivity creates a single message with multiple recipients 2. This single message is queued in fan-out queue (marked as providing quick response) 3. A background worker processes the fan-out message 4. The worker re-enqueues individual messages in outbox 5. These are then processed independently 6. Three delivery outcomes: Recipient 1 (fast delivery), Recipient 2 (fast delivery), and Recipient 3 (slow server) The diagram highlights how the fan-out approach moves the heavy processing out of the response path, providing faster API response times while maintaining the same delivery characteristics.

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

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.

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

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.

@sakurasubnet@bumscode.com

Is the world in need of a federated Craigslist/Kleinanzeigen platform? I am currently thinking about a project to dig into development and learning or stay with and using .

EDIT: There is already something like that on the fediverse! It's called Flohmarkt. Thanks for the comments mentioning that!
codeberg.org/flohmarkt/flohmar

codeberg.org

flohmarkt

federated decentral classified ad software using activitypub

Fedifyの関連プロジェクトをご紹介したいと思います。ActivityPubアプリケーション開発をより簡単にするツール群です:

Fedify :fedify:

Fedify@fedify)はActivityPubやその他のフェディバース標準を活用する連合型サーバーアプリケーションを構築するためのTypeScriptライブラリです。Activity Vocabularyの型安全なオブジェクト、WebFingerクライアント・サーバー、HTTP Signaturesなどを提供し、ボイラープレートコードを削減してアプリケーションロジックに集中できるようにします。

Hollo :hollo:

Hollo@hollo)はFedifyで動作するお一人様用マイクロブログサーバーです。個人向けに設計されていますが、ActivityPubを通じて完全に連合化されており、フェディバース全体のユーザーと交流することができます。HolloはMastodon互換APIを実装しているため、独自のウェブインターフェースがなくても、ほとんどのMastodonクライアントと互換性があります。

Holloはまた、正式リリース前の最新Fedify機能をテストする実験場としても活用されています。

BotKit :botkit:

BotKit@botkit)は私たちの最も新しいメンバーで、ActivityPubボットを作成するために特別に設計されたフレームワークです。従来のMastodonボットとは異なり、BotKitはプラットフォーム固有の制限(文字数制限など)に縛られない独立したActivityPubサーバーを作成します。

BotKitのAPIは意図的にシンプルに設計されており、単一のTypeScriptファイルで完全なボットを作成できます!


これら三つのプロジェクトはすべて@fedify-dev GitHubオーガニゼーションでオープンソースとして公開されています。それぞれ異なる目的を持っていますが、ActivityPub開発をより身近にし、フェディバースのエコシステムを拡大するという共通の目標を共有しています。

これらのプロジェクトを試してみたり、開発に貢献したりすることに興味がある場合は、以下をご覧ください:

botkit.fedify.dev

BotKit by Fedify

A framework for creating your ActivityPub bots

자매 프로젝트들을 소개해 드리고자 합니다. 애플리케이션 개발을 더 쉽게 만들어주는 관련 도구들입니다:

Fedify :fedify:

Fedify(@fedify)는 ActivityPub와 다른 () 표준을 기반으로 연합 서버 애플리케이션을 구축하기 위한 라이브러리입니다. Activity Vocabulary를 위한 타입 안전한 객체, WebFinger 클라이언트·서버, HTTP Signatures 등를 제공하여 반복적인 코드를 줄이고 애플리케이션 로직에 집중할 수 있게 해줍니다.

Hollo :hollo:

Hollo(@hollo)는 Fedify로 구동되는 1인 사용자용 마이크로블로깅 서버입니다. 1인 사용자를 위해 설계되었지만, ActivityPub를 통해 완전히 연합되어 연합우주 전체의 사용자들과 상호작용할 수 있습니다. Hollo는 Mastodon 호환 API를 구현하여 자체 웹 인터페이스 없이도 대부분의 Mastodon 클라이언트와 호환됩니다.

Hollo는 또한 정식 출시 전에 최신 Fedify 기능을 테스트하는 실험장으로도 활용되고 있습니다.

BotKit :botkit:

BotKit(@botkit)은 저희의 가장 새로운 구성원으로, ActivityPub 봇을 만들기 위해 특별히 설계된 프레임워크입니다. 전통적인 Mastodon 봇과 달리, BotKit은 플랫폼별 제한(글자 수 제한 등)에 구애받지 않는 독립적인 ActivityPub 서버를 만듭니다.

BotKit의 API는 의도적으로 단순하게 설계되어 단일 TypeScript 파일로 완전한 봇을 만들 수 있습니다!


세 프로젝트 모두 @fedify-dev GitHub 조직에서 오픈 소스로 공개되어 있습니다. 각기 다른 목적을 가지고 있지만, ActivityPub 개발을 더 접근하기 쉽게 만들고 연합우주 생태계를 확장한다는 공통된 목표를 공유합니다.

이러한 프로젝트를 사용해보거나 개발에 기여하는 데 관심이 있으시다면, 다음을 확인해보세요:

botkit.fedify.dev

BotKit by Fedify

A framework for creating your ActivityPub bots

We'd like to introduce the project family—a set of related tools that make building applications more accessible:

Fedify :fedify:

Fedify (@fedify) is a library for building federated server applications powered by ActivityPub and other standards. It provides type-safe objects for Activity Vocabulary, WebFinger client/server, HTTP Signatures, and more—eliminating boilerplate code so you can focus on your application logic.

Hollo :hollo:

Hollo (@hollo) is a single-user microblogging server powered by Fedify. While designed for individual users, it's fully federated through ActivityPub, allowing interaction with users across the fediverse. implements Mastodon-compatible APIs, making it compatible with most Mastodon clients without needing its own web interface.

Hollo also serves as our testing ground for bleeding-edge Fedify features before they're officially released.

BotKit :botkit:

BotKit (@botkit) is our newest family member—a framework specifically designed for creating ActivityPub bots. Unlike traditional Mastodon bots, creates standalone ActivityPub servers that aren't constrained by platform-specific limitations (like character counts).

BotKit's API is intentionally simple—you can create a complete bot in a single TypeScript file!


All three projects are open source and hosted under the @fedify-dev GitHub organization. While they serve different purposes, they share common goals: making ActivityPub development more accessible and expanding the fediverse ecosystem.

If you're interested in trying any of these projects or contributing to their development, check out:

botkit.fedify.dev

BotKit by Fedify

A framework for creating your ActivityPub bots

We've been working on adding custom background task support to as planned for version 1.5.0. After diving deeper into implementation, we've realized this is a more substantial undertaking than initially anticipated.

The feature would require significant API changes that would be too disruptive for a minor version update. Therefore, we've decided to postpone this feature to Fedify 2.0.0.

This allows us to:

  • Design a more robust and flexible worker architecture
  • Ensure better integration with existing task queue systems
  • Properly document the new APIs without rushing

We believe this decision will result in a more stable and well-designed feature that better serves your needs. However, some smaller improvements from our work that don't require API changes will still be included in Fedify 1.5.0 or subsequent minor updates.

We appreciate your understanding and continued support.

If you have specific use cases or requirements for background task support, please share them in our GitHub issue. Your input will help shape this feature for 2.0.0.

github.com

Support custom background tasks in worker · Issue #206 · fedify-dev/fedify

NoteWe've decided to postpone custom background task support to Fedify 2.0.0 instead of 1.5.0 as originally planned. This feature requires significant API changes that would be too disruptive for a...

Patch releases for versions 1.0.21, 1.1.18, 1.2.18, 1.3.14, and 1.4.7 are now available. These updates address two important bugs across all supported release lines:

  1. Fixed a WebFinger handler bug that prevented matching acct: URIs with port numbers in the host. Thanks to @revathskumar for reporting and debugging the bug!
  2. Resolved server errors that occurred when invalid URLs were passed to the base-url parameter of followers collections.

We recommend all users upgrade to these latest patch versions for improved stability and federation compatibility.

Release Fedify 1.4.7 · fedify-dev/fedify

Released on March 20, 2025. Fixed a bug of WebFinger handler where it had failed to match acct: URIs with a host having a port number. [#218, #219 by Revath S Kumar] Fixed a server error thrown...

@fedify@hollo.social · Reply to Max

@PossiblyMax Great question about our queue implementation! Fedify doesn't actually create separate physical queues, but rather uses a single logical queue where each message contains its own destination information.

For resource management, we generally rely on the underlying queue implementation (Redis, PostgreSQL, etc.) to handle concurrent processing efficiently. Since version 1.0.0, we've introduced ParallelMessageQueue which processes multiple messages concurrently with a configurable worker count—usually set close to your CPU core count for IO-bound operations.

We don't spin up new queues dynamically; instead, we focus on making the message processing scalable. You can control the parallelism level when using ParallelMessageQueue, and for high-volume instances, you can horizontally scale by running multiple worker processes that connect to the same shared queue backend.

This approach keeps the architecture simpler while still allowing for good throughput and resource utilization that can scale with your instance size.

fedify.dev

Message queue | Fedify

Fedify docs

@fedify@hollo.social · Reply to Max

@PossiblyMax Great question about our queue implementation! Fedify doesn't actually create separate physical queues, but rather uses a single logical queue where each message contains its own destination information.

For resource management, we generally rely on the underlying queue implementation (Redis, PostgreSQL, etc.) to handle concurrent processing efficiently. Since version 1.0.0, we've introduced ParallelMessageQueue which processes multiple messages concurrently with a configurable worker count—usually set close to your CPU core count for IO-bound operations.

We don't spin up new queues dynamically; instead, we focus on making the message processing scalable. You can control the parallelism level when using ParallelMessageQueue, and for high-volume instances, you can horizontally scale by running multiple worker processes that connect to the same shared queue backend.

This approach keeps the architecture simpler while still allowing for good throughput and resource utilization that can scale with your instance size.

fedify.dev

Message queue | Fedify

Fedify docs

Just released @fedify/markdown-it-mention v0.3.0! This update adds support for bare handles (e.g., @username without domain) with the new localDomain option, allowing you to specify the domain for these shortened mentions.

Install via npm, Bun, or Deno:

npm add @fedify/markdown-it-mention@0.3.0
bun add @fedify/markdown-it-mention@0.3.0
deno add jsr:@fedify/markdown-it-mention@0.3.0

jsr.io

PluginOptions.localDomain - @fedify/markdown-it-mention - JSR

@fedify/markdown-it-mention on JSR: A markdown-it plugin that parses and renders Mastodon-style @mentions

@julian@community.nodebb.org · Reply to Fedify: ActivityPub server framework

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

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.

@bthj@hachyderm.io
@liaizon@wake.st
@julian@fietkau.social · Reply to julian

@julian@community.nodebb.org Can I confess something?

When @fedify first came out, I was worried that everyone might abandon their ActivityPub implementations for the convenience of "letting someone else handle it" and that the fediverse could run into a Chrome-esque engine monopoly. 😱

I'm honestly surprised how few projects rely on Fedify to this day. Turns out people have too much fun sticking their hands into the pipes after all! 😄

@julian@community.nodebb.org · Reply to Fedify: ActivityPub server framework
@Yohei_Zuho@mstdn.y-zu.org
@Yohei_Zuho@mstdn.y-zu.org