Fibril documentation
This content is for the 0.2 version. Switch to the latest version for up-to-date documentation.
Fibril is a lightweight message broker focused on durable delivery, explicit acknowledgements, leasing, retries, and asynchronous workflow coordination. It also has partitioned queues for scale, exclusive consumer groups for ordered parallel consumption, Plexus streams for fan-out where every subscriber sees every record, and an experimental clustered mode with partition ownership, replication, and failover for both queues and streams. The broker is implemented in Rust, but the user-facing model is about durable messaging rather than a Rust-only ecosystem.
It is currently pre-alpha. The useful baseline is working, but APIs, persistence formats, protocol details, and operational behavior can still change. The clustering and replication paths are experimental and not yet production-ready high availability.
Where to start
Section titled “Where to start”- Follow the quickstart to run the broker from source.
- Use the client guide for Rust, TypeScript, and Python publishing and subscription examples.
- Use the admin dashboard guide for queues, settings, message inspection, and DLQ replay.
- Read the core model for the queue lifecycle.
- Read retries and delays and dead lettering for reliability features and their current limits.
- Read consumer groups for ordered, scalable consumption across many consumer instances.
- Read Plexus streams for fan-out delivery where every subscriber sees every record, with per-stream durability tiers.
- Read clustering and replication for the experimental multi-broker ownership, replication, and failover path, or try a cluster with Docker in under a minute.
- Read many idle queues if your workload defines many queues but only uses a few at once.
- Check project status before depending on a feature.
- Check implemented surface when you need the detailed answer for whether a path is wired and under what conditions.
- Check the roadmap for recently landed work and near-term pending items.
- Use the optimization log for benchmark-first performance investigations.
Design intent
Section titled “Design intent”Message handling should read like the intent of the system:
while let Some(msg) = sub.recv().await { process(msg.content()?).await?; msg.complete().await?;}Messages can also be retried or failed explicitly:
msg.retry().await?;msg.retry_after(30).await?;msg.fail().await?;Delayed retry is wired through the broker, protocol, and the Rust, TypeScript, and Python clients. See project status.
The protocol and storage model intentionally lean toward small common-case records. Always-present message metadata is stored as positional metadata, not repeated header-map keys, and uncommon operations use distinct frames or events instead of adding optional fields to hot paths. For example, delayed publish uses a delayed-publish frame rather than adding a delay field to every publish frame.
This is not a rule against richer commands. Infrequent configuration commands can carry complete settings when that makes atomic updates clearer, such as declaring a queue with all of its settings in one command.
Current documentation
Section titled “Current documentation”These docs are the frozen snapshot of the 0.2 release line. The documentation for the active pre-1.0 codebase lives at the site root and moves ahead of this snapshot.