Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Queue Rabbitmq Laravel Package

dejwcake/laravel-queue-rabbitmq

RabbitMQ queue driver for Laravel. Connects Laravel's queue system to RabbitMQ so jobs publish and consume over AMQP, with configurable exchanges, routing, delays, and connections. A drop-in alternative to the default queue driver, configured through queue.php for reliable background processing.

View on GitHub
Deep Wiki
Context7

Getting Started

This package provides a RabbitMQ queue driver for Laravel, exposing the familiar dispatch() API on the producer side and an Artisan consumer (rabbitmq:consume) on the worker side. Day to day it is a drop-in replacement for the database/redis drivers, so the first steps are configuration, not code.

  1. Require the package (composer require vyuldashev/laravel-queue-rabbitmq) and confirm the PHP constraint: v15.1.0 requires ^8.1. Older pins (^8.0) can never resolve, so run composer why-not if the install fails.
  2. Add a rabbitmq connection in config/queue.php (host, port, user, password, vhost, queue, exchange, exchange_type, routing key) and point QUEUE_CONNECTION=rabbitmq at it in .env.
  3. Define the topology declaratively in that config block so the driver declares the exchange and queue on first use — no manual rabbitmqadmin step needed.
  4. Skip queue:work; run php artisan rabbitmq:consume --queue=default under Supervisor, systemd, or a Kubernetes Job. Everything else (dispatch(new ProcessPodcast), ->onQueue(), ->delay(), queue:failed) behaves exactly as you already know.

First real use case: move an existing redis-backed job onto RabbitMQ for at-least-once delivery, routing, and per-queue isolation, with zero changes to the job classes themselves. Verify end to end by dispatching once with QUEUE_CONNECTION=rabbitmq and watching rabbitmqctl list_queues name messages_ready messages_unacknowledged consumers — you should see the consumer count go to 1 and the message move from ready to acked.

Implementation Patterns

Producer side — stay boring. Dispatch through the normal API and select the connection explicitly at the call site (->onConnection('rabbitmq')->onQueue('exports')) rather than relying on the default. This makes it obvious in code review which jobs cross the broker and lets you keep sync in tests without surprises. Keep job payloads small and serialisable; RabbitMQ messages are JSON and a fat model graph will bite you on redelivery.

Consumer side — one Supervisor program per queue, with explicit limits.

command=php /var/www/artisan rabbitmq:consume --queue=exports --tries=3 --timeout=90 --memory=512 --max-jobs=1000
autorestart=unexpected
exitcodes=0,12
stopwaitsecs=95

The --memory limit is the pattern most teams use to work around long-lived worker leaks; the worker exits and the process manager restarts it. --max-jobs and --max-time are the other two levers, and on Laravel 13.18+ they now genuinely stop the consumer (they silently did nothing before v15.1.0).

Batch and one-shot consumers. With --max-jobs, --stop-when-empty, and --stop-when-empty-for functioning again, rabbitmq:consume becomes viable for cron-driven or Kubernetes Job workloads that should drain a queue and exit. Prefer --max-jobs (deterministic) over --stop-when-empty (depends on how the driver infers idleness) when you are scripting a guaranteed exit.

Graceful shutdown and pause. The SIGUSR2 pause hook is useful for draining a pod during deploy: pause the consumer, let in-flight jobs finish, then SIGTERM. In v15.1.0 a paused consumer also exits on SIGTERM, on queue:restart, and when time/memory limits trip — which is what you want for rolling deploys, but it does mean a paused worker is no longer immortal.

Observability via WorkerStopping. Register a listener and record the integer status, stop reason, connection, and queue. This is the cleanest place to emit a metric for "workers killed by memory limit" versus "workers exited cleanly", and the shape of the event is now version-consistent. Since the consumer now exits with the worker's code, your process manager and your metrics agree on why a worker died.

Custom Consumer subclasses. If you have extended the consumer to add behaviour around pause or stop conditions, hook the stop-condition check rather than pauseWorker() — see the gotchas below.

Gotchas and Tips

  • Exit codes changed in v15.1.0 — audit your process manager first. The command used to always exit 0; it now exits with the worker's code, e.g. 12 on memory limit, matching queue:work. Supervisor configs with exitcodes=0 or autorestart=unexpected will now restart-loop on a limit hit; Kubernetes Jobs with restartPolicy: Never will show Failed instead of Complete. This is the single most likely thing to break your deployment.
  • Consumer::pauseWorker() is no longer called. If you overrode it (inherited from Worker), that logic is now dead code. Move it into the consumer's own stop-condition path. Silent regression, no error thrown.
  • Upgrade if you run Laravel 13.31+. Every delivery failed with an ArgumentCountError in Worker::registerTimeoutHandler() — i.e. zero jobs processed. On 13.18+ to 13.30, --max-jobs/--stop-when-empty* never stopped the consumer, so supposedly batch workers ran forever. If your queue depth charts look odd on recent Laravel, this is why.
  • Version matrix matters when debugging. The worker loop has three distinct signatures across Laravel 13 (13.0–13.17, 13.18–13.30, 13.31+). Pin both laravel/framework and this package, and include both versions in bug reports — a lot of "consumer misbehaves" issues are a mismatched pair.
  • declareExchange() is now synchronous. It waits for RabbitMQ's confirm, so isExchangeExists() immediately after is reliable and a rejected declaration throws at that point rather than surfacing later as a confusing publish failure. Keep topology declaration in a deploy/bootstrap step, not in the request path — the confirm round-trip is wasted latency on hot paths.
  • At-least-once is real. Redelivery happens on connection drops, nacks, and killed workers. Jobs must be idempotent, and retry_after in config must exceed your job timeout, or RabbitMQ will hand the same message to a second worker mid-execution.
  • Debugging toolkit: rabbitmqctl list_queues name messages_ready messages_unacknowledged consumers for broker state, php artisan queue:failed and queue:retry for poison messages, and --verbose on the consumer for per-job output. A consumer count of 0 with a growing ready count almost always means a crashed worker, not a lost message.
  • Extension points worth knowing: the WorkerStopping event (status, reason, connection, queue), a container binding for a custom consumer class, and the queue config's exchange/queue declaration block. There is no supported hook to change the ack policy, so don't plan around one.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource