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

Queue Laravel Package

cakephp/queue

A CakePHP queue plugin for running background jobs with job classes, CLI workers, and configurable queue backends. Offload time-consuming tasks, process work asynchronously, and keep web requests fast and responsive.

View on GitHub
Deep Wiki
Context7

Getting Started

cakephp/queue is a thin, queue-interop-compatible wrapper: it gives you a QueueManager, a Queue facade over an enqueue transport, a Processor that turns messages into job objects, and CakePHP console glue. It is not a Laravel package — the ergonomics (Configure::read('Queue'), plugin bootstrap, bin/cake) assume CakePHP. As a Laravel developer you should treat it as "an enqueue transport with a job-dispatch convention on top," and budget a small amount of wiring.

Read in this order:

  1. README.md — config shape and the Queue API surface.
  2. src/QueueManager.php — how configs map to DSNs and how get() caches instances.
  3. src/Queue.php — push, pushMany, consume, receive/acknowledge/reject.
  4. src/Processor.php + src/Job/JobInterface.php — job resolution rules and the run() contract.

Minimal path (evaluating it, not committing):

composer require cakephp/queue enqueue/fs   # fs for local; redis/amqp-lib for real
// CakePHP: config/app.php. Laravel: mirror into config/queue.php and register the manager yourself.
'Queue' => [
    'default' => ['url' => env('QUEUE_URL', 'file:///tmp/queue')],
],
use Cake\Queue\QueueManager;

$queue = QueueManager::get('default');
$queue->push('App\Job\SendInvoice', ['invoiceId' => 42]);

// worker
$queue->consume();

First real use case: a fire-and-forget webhook or invoice-email job on the fs transport, confirm the JSON file appears on disk, then change only the DSN to redis://… or amqp://…. That DSN swap is the package's actual selling point.

Implementation Patterns

Config as DSN, one block per queue. Keep every transport detail in the URL string and read it from env. Define default, high, low configs mapped to separate queues rather than inventing a priority field inside the payload — priority belongs in the routing key.

Job class = envelope, service = logic. The job should do nothing but unpack the message and call a plain application service. This keeps it testable without a queue and lets you reuse the service from an HTTP controller.

namespace App\Job;

use Cake\Queue\Job\JobInterface;
use Cake\Queue\Queue\Message;

class SendInvoice implements JobInterface
{
    public function run(Message $message): void
    {
        // 2.x used run(array $data, Queue $queue); 3.x passes a Message. Check your major.
        $data = $message->getParsedBody();
        app(\App\Services\InvoiceMailer::class)->send($data['invoiceId']);
    }
}

Use aliases for cross-environment routing. The processor resolves either a FQCN or a <config>.<alias> name registered in configuration. Aliases let staging route default.Email to a different class or queue without touching call sites.

Push from the request, consume from a supervised process. The producer path is push/pushMany inside a request (bulk import → one pushMany, not a loop of push). The consumer path is a long-running CLI process under systemd/supervisor. Do not consume inside a web request.

Laravel integration is a service provider plus one artisan command. Bind the QueueManager as a singleton, hydrate it from config/queue.php, then write a queue:work-shaped command that calls consume() with iteration/runtime caps so deploys can restart it cleanly. You are essentially rebuilding Horizon's process model minus the dashboard.

Test without consuming. Swap the DSN to enqueue/null (or fs into a temp dir) and assert on the pushed envelope, or inject a spy Queue into the producer. Integration tests that actually consume are the slowest and flakiest part of a queue suite — keep them few.

Make run() idempotent. All enqueue transports are at-least-once. Key side effects on a message id or a business key (invoiceId + status), or you will double-send on every worker crash.

Gotchas and Tips

  • Framework coupling is real. It depends on cakephp/core, Configure, and Cake's console layer. In Laravel you'll be constructing objects manually and ignoring the shell commands. Budget a day, not an hour.
  • Transports are separate packages. cakephp/queue alone does nothing — you must also install enqueue/redis, enqueue/amqp-lib, enqueue/fs, etc. Version pins in the interop ecosystem are conservative; check PHP compatibility before committing.
  • Unknown job names fail at consume time, not push time. A typo in the class name or alias surfaces only in the worker, and depending on processor config the message may be requeued — which can turn a typo into an infinite retry loop. Log and alarm on rejections.
  • No out-of-the-box dead-letter queue. You get reject()/requeue() primitives. If you want DLQ behaviour you implement it: catch in the job or wrap the processor, increment an attempt counter in the payload, and reject past a threshold.
  • JSON round-trips lose types. Dates become strings, objects become arrays, integers can become floats in some paths. Pass scalars and IDs, rehydrate in the job.
  • Payload size is transport-specific (SQS ~256KB, AMQP frames, Redis effectively memory-bound). Keep messages as pointers to rows/files, not the data itself.
  • Long-running consumers leak. Orphaned DB connections and growing memory are the default failure mode. Use maxIterations/maxRuntime consumption options and recycle the process; also restart workers on deploy or they'll run old code.
  • Debug locally with fs. The transport writes human-readable JSON files you can cat. Add a --verbose flag to your worker command mirroring Cake's consumption verbosity and print the raw envelope on failure — it's faster than attaching a debugger.
  • Consumption extension points are the Cake\Queue\Consumption\* traits, but documentation is thin. Read src/Consumption/ directly; wrapping consume() in your own try/finally is usually simpler than composing traits.
  • Community surface is small (≈36 stars, no dependents). Expect to answer questions from the source, not from blog posts. Pin the version, and diff the JobInterface signature and QueueManager config keys between majors before upgrading.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin