goopil / rabbit-rs-native
High-performance RabbitMQ transport for PHP and Laravel, powered by Rust
Package info
github.com/Goopil/php-rabbit-rs
Language:Rust
Type:php-ext
Ext name:ext-rabbit_rs
pkg:composer/goopil/rabbit-rs-native
Requires
- php: ^8.2
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.3.14
- v0.3.13
- v0.3.12
- v0.3.11
- v0.3.10
- v0.3.9
- v0.3.8
- v0.3.7
- v0.3.6
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.9
- v0.0.8
- v0.0.7
- v0.0.6
- v0.0.5
- v0.0.4
- v0.0.3
- v0.0.2
- v0.0.1
- dev-chore/unpin-ci-runners
- dev-feat/ext-php-rs-016
- dev-fix/release-pie-packagist
- dev-fix/release-setup-php
- dev-chore/rust-deps-refresh
- dev-fix/audit-2026-10-01
- dev-fix/audit-2026-10-01-phpstan
- dev-fix/audit-2026-10-01-core
- dev-fix/audit-2026-10-01-php-ext
- dev-fix/audit-2026-10-01-laravel
- dev-fix/audit-2026-10-01-hygiene
- dev-feat/native-fallback-for-management-api
- dev-ffi-single-copy
- dev-feature/connection-blocked-signal
- dev-fix/recovery-loss-recoverability
- dev-test/stabilize-route-binding
- dev-chore/release-v0.3.7
- dev-fix/topology-verify-flake
- dev-fix/closed-pop-storm
- dev-docs/refresh-0.3.6
- dev-fix/stop-when-empty-convergence
- dev-fix/prefetch-env-json
- dev-chore/release-v0.3.6
- dev-feat/default-prefetch-1000
- dev-feat/adaptive-resize-consume
- dev-fix/consumer-backpressure-reliability
- dev-fix/adaptive-prefetch-signal
- dev-chore/rustls-security-bump
- dev-perf/stock-aware-flush
- dev-bench/consume-attribution
- dev-bench/fire-and-forget-consume-semantics
- dev-ref/sonarcloud-scope-and-fixes
This package is auto-updated.
Last update: 2026-10-25 21:11:18 UTC
README
Keep writing PHP. Let Rust handle RabbitMQ.
Rabbit RS is a native RabbitMQ runtime for PHP and Laravel workers, designed to stay alive. Your application keeps using Laravel's standard queue API; Rabbit RS handles connections, publisher confirms, recovery, and long-running consumption in a native Rust runtime.
The product is built around one feature: the long-running consumer — a worker that multiplexes many queues per broker connection, survives broker restarts and network failures, and keeps settling deliveries through recovery without manual intervention. A supervised fan-out command runs one worker per connection to span vhosts and brokers.
Delivery is at-least-once. Once a message is accepted into the confirmed delivery path, silent loss is unacceptable; duplicates are permitted and must remain measurable.
Quick start
Step 1 — Install the native extension:
pie install goopil/rabbit-rs-native
Step 2 — Install the Laravel queue driver:
composer require goopil/rabbit-rs-laravel
Step 3 — Configure the connection:
Add a rabbit-rs connection to config/queue.php (one connection = one broker = one native pool):
'connections' => [ 'rabbit-rs' => [ 'driver' => 'rabbit-rs', 'queue' => env('RABBIT_RS_QUEUE', 'default'), 'hosts' => env('RABBIT_RS_HOSTS', '127.0.0.1:5672'), 'username' => env('RABBIT_RS_USERNAME', 'guest'), 'password' => env('RABBIT_RS_PASSWORD', 'guest'), ], ],
Configuration is connection-first — broker, credentials, routes, safety mode, and worker profile all live on the queue connection. The full reference (every key, defaults, validation, and the safety modes) is packages/laravel-queue/docs/reference.md. Optionally publish the cross-cutting defaults:
php artisan vendor:publish --tag="rabbit-rs-config"
Step 4 — Publish and consume a job:
// app/Jobs/ProcessOrder.php class ProcessOrder implements ShouldQueue { use Dispatchable, Queueable; public function __construct(public int $orderId) {} } // Dispatch ProcessOrder::dispatch(42);
# Consume php artisan queue:work rabbit-rs # or the supervised fan-out across every rabbit-rs connection: php artisan rabbit-rs:work
No extra configuration required: pop the queue directly — it is the connection's queue key — or declare more queues under the subscriptions escape hatch. A pop addressed to one queue of a multi-queue connection gets a dedicated single-queue consumer, so it never draws from the sibling queues (see packages/laravel-queue/docs/reference.md).
What it does
- Long-running consumer — one worker multiplexes subscriptions across many queues on its connection and survives broker restarts without manual intervention
- At-least-once delivery — publisher confirms and mandatory routing enabled by default; every publish is tracked to ACK, return, or timeout
- Deterministic recovery — connection, channels, exchanges, queues, bindings, QoS, then consumers, in a fixed order
- Weighted-fair scheduling — proportional delivery shares across subscriptions by weight
- Connection-generation-aware tokens — stale ACKs are rejected so RabbitMQ redelivers
- Bounded replay buffer — unconfirmed publications survive connection recovery in bounded memory, replayed with the same
message_id - Multi-broker fan-out — a vhost owns a distinct AMQP connection; define one connection per broker/vhost and
rabbit-rs:worksupervises them all - Auto-scaling supervisor —
rabbit-rs:workgrows its fleet under load and releases idle workers, driven by management-API queue depth (--min-workers/--max-workers), with one-shot--once/--stop-when-emptymodes for CI drains - Octane lifecycle — flush, reload, and stop hooks prevent channel leaks
- No unsafe Rust —
#![forbid(unsafe_code)]across the entire workspace
On the lab consumption workload (transport harness, unit pop+ack — php-amqplib pulls one
basic_getper message, rabbit-rs runs a pushed subscription with prefetch 64 and manual acks; the publish side is blind on both), rabbit-rs reaches 12 963 ops/s against 2 255 ops/s for php-amqplib on the same session, interleaved runs (10 000 msgs/round × 10 rounds), with 0 losses and 0 duplicates in every archived run. Harness, methodology, and archived results: benchmarks/README.md; the numbers above are from benchmarks/results/round-2-rebench/README.md.
Support contract
| Dimension | Support |
|---|---|
| PHP | 8.2, 8.3, 8.4, and 8.5 — NTS and ZTS on Linux; NTS only on macOS (ZTS deferred) |
| Laravel | 12 and 13 (for the Laravel queue driver) |
| SAPIs | CLI, PHP-FPM, and Octane (FrankenPHP, RoadRunner, Open Swoole, Swoole) |
| RabbitMQ | 4.2.9 or newer (the CI lab runs 4.2.9) |
| Platforms | Linux x86_64 or ARM64 (glibc or musl) — pre-compiled binaries via PIE; macOS ARM64 — pre-compiled binary from GitHub Releases and Homebrew |
| Native extension | ext-rabbit_rs as a Composer suggestion (version range declared in the driver's composer.json): composer install succeeds without it, and connections fail at resolution with a typed error until you pie install goopil/rabbit-rs-native |
| Delivery | At-least-once: duplicates are permitted and measured (duplicates_total, messages_redelivered); silent loss after confirmed-path acceptance is a bug |
- Rust 1.98.1 (contributors only — see Contributing)
Distribution channels
Rabbit RS is distributed via three channels:
| Package | Channel | Purpose |
|---|---|---|
goopil/rabbit-rs-native |
PIE | Native PHP extension (Linux and macOS binaries) |
goopil/rabbit-rs-laravel |
Packagist | Laravel queue driver (PHP source) |
rabbit-rs |
Homebrew | Native PHP extension (macOS binary, alternative to PIE) |
ghcr.io/goopil/php-rabbit-rs |
Docker install images | Copy the pre-compiled extension into your PHP image (Linux) |
PIE selects the correct pre-compiled binary for your PHP version, architecture, operating system, libc, and thread-safety mode — including macOS Apple Silicon. Homebrew offers the same macOS binaries through the tap. Composer installs the Laravel bridge but does not install, verify, or modify system PHP: ext-rabbit_rs is a Composer suggestion and the driver fails at connection resolution until the extension is loaded (PIE installs the binary).
macOS
PIE (Apple Silicon):
pie install goopil/rabbit-rs-native
Homebrew (Apple Silicon, alternative):
brew tap goopil/rabbit-rs brew install rabbit-rs
Requires PHP 8.2, 8.3, 8.4, or 8.5 (Homebrew PHP for the tap).
Manual install (Apple Silicon):
On Apple Silicon (ARM64), download the pre-compiled binary from GitHub Releases and load it manually:
# Download the matching asset for your PHP version unzip php_rabbit_rs-*_php8.4-arm64-darwin-bsdlibc-nts.zip cp rabbit_rs.so $(php-config --extension-dir)/rabbit_rs.so echo "extension=rabbit_rs" > $(php-config --ini-dir)/ext-rabbit_rs.ini php -m | grep rabbit_rs
Alternatively, build from source:
git clone https://github.com/Goopil/php-rabbit-rs.git
cd php-rabbit-rs
./scripts/install.sh --release
Intel Macs (x86_64) are not distributed as pre-compiled binaries — build from source with ./scripts/install.sh --release.
Docker (Linux)
Copy the pre-compiled extension into your PHP image — no build tools, no PIE step:
COPY --from=ghcr.io/goopil/php-rabbit-rs:latest-php8.5 /usr/local/ /usr/local/
Tags: latest-php8.2 through latest-php8.5, -alpine variants (libgcc bundled), and version-pinned tags (v0.3.14-php8.5-alpine), published on each release by install-images.yml. The images carry the NTS binary only: they COPY over php:N-cli bases, which are NTS. For ZTS (e.g. the official FrankenPHP images), install via PIE or download the Linux ZTS release assets directly (see Octane notes).
Not V1 distribution channels:
- PECL
- Debian/RPM/APK packages
- Composer plugins that install binaries
- Full PHP images bundling the extension
These are explicitly out of scope for V1. Use PIE or the Docker install images above in your Dockerfile — see Installation.
Stability
Stability is proven by scheduled kill-soaks, not by hope. The nightly soak
runs a sustained publish/consume worker against a real RabbitMQ cluster and
kills the broker repeatedly: the archived 60-minute run completed with
0 missing messages and 297/297 automatic reconnects
(benchmarks/results/round-k-soak/), and every scenario in the chaos suite
asserts the zero-loss invariant. Results are re-verified nightly in CI
(soak workflow).
Delivery stays at-least-once under all of it — see Limitations for what that means in practice.
Limitations
Read before betting a pipeline on this.
- At-least-once means duplicates are possible — by contract, and measured. The broker redelivers any delivery that is not acknowledged (worker crash, channel loss, recovery), so consumers must treat an extra copy as normal: jobs must be idempotent. Duplicates are counted per run and become possible after any reconnect. The counters (
duplicates_total,messages_redelivered) and idempotency guidance live in Reliability. - The replay buffer is in-process memory, not durability. Unconfirmed publications survive connection recovery in a bounded in-process buffer (1024 publications / 64 MiB by default) and are replayed with the same
message_idand original deadline. A PHP process crash empties it: the broker may never have received those messages, and nothing redelivers them to you. Broker redelivery after a crash covers the consume side (duplicates, not loss) — it is not publish durability. For cross-process durability you need an external outbox, which Rabbit RS does not include (What the replay buffer is not).
Documentation
| Topic | File |
|---|---|
| Getting started (native extension) | docs/getting-started.md |
| Reference — installation, reliability, troubleshooting | docs/reference.md |
| Getting started (Laravel driver) | packages/laravel-queue/docs/getting-started.md |
| Reference — configuration, usage, topology, operations, recipes | packages/laravel-queue/docs/reference.md |
| Benchmark harness and archived results | benchmarks/README.md |
Migration guides — from php-amqplib / from laravel-queue-rabbitmq |
docs/migration-from-php-amqplib.md · docs/migration-from-laravel-queue-rabbitmq.md |
| Laravel example app — job, Dockerfile, supervisor config | examples/laravel/ |
| Development guide | docs/development.md |
| Security policy — reporting vulnerabilities | SECURITY.md |
Contributing
See CONTRIBUTING.md for the full guide. Quick reference:
# Build the extension cargo build -p rabbit-rs-php --features extension-tests # Run tests ./scripts/test-laravel.sh # Laravel Unit + Feature (no extension) ./scripts/test-extension.sh # PHP extension (Pest + PHPT) cargo test -p rabbit-rs-core # Rust core # Quality gate ./scripts/check.sh
For architecture, build system, test strategy, and common pitfalls, see docs/development.md.
License
MIT. See LICENSE.