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

Sqs Queue Driver Bundle Laravel Package

mcfedr/sqs-queue-driver-bundle

Symfony bundle that lets you use Amazon SQS as your queue driver, so you can offload background jobs to AWS without rewriting your existing messaging code.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. A Laravel developer's first job is to decide whether it fits at all: it plugs into symfony/messenger and the Symfony DI container. If you are in a Laravel-only codebase, stop here and use Laravel's built-in SQS queue driver (config/queue.php, php artisan queue:work sqs) — this bundle gives you nothing Laravel hasn't already shipped. It becomes interesting only when you are working in a Symfony app (or a hybrid app that already boots a Symfony kernel alongside Laravel, e.g. shared workers/legacy components).

Mental model translation for a Laravel dev:

Laravel Symfony Messenger (this bundle)
Queue connection (sqs) Transport (sqs://... DSN)
Job class Message class (plain DTO)
dispatch(new Job) $bus->dispatch(new Message)
php artisan queue:work bin/console messenger:consume <transport>
failed_jobs table Failure transport / DLQ
queue:retry messenger:failed:retry

Minimal steps:

  1. composer require mcfedr/sqs-queue-driver-bundle. Symfony Flex should register it in config/bundles.php; if not, add Mcfedr\SqsQueueDriverBundle\...Bundle::class => ['all' => true].
  2. Ensure symfony/messenger is installed and you have AWS credentials in the standard chain (env vars, ~/.aws, or an instance/task IAM role).
  3. Configure a transport in config/packages/messenger.yaml using the DSN the bundle registers (typically sqs://... with region, queue_name, and credentials resolved via the AWS SDK/async-aws credential chain).
  4. Route a message class to that transport and consume it.
# config/packages/messenger.yaml
framework:
  messenger:
    transports:
      async_sqs:
        dsn: '%env(SQS_DSN)%'
        options:
          queue_name: 'app-tasks'
          region: 'eu-west-1'
    routing:
      'App\Message\SendInvoice': async_sqs

First use case: a single fire-and-forget job (e.g. "send invoice email") dispatched from a controller/handler and consumed by a long-running messenger:consume async_sqs worker under Supervisor/systemd.

Where to look first: the bundle's DependencyInjection/*Extension.php to see exactly which transport factory/service it registers and which options it accepts, then the README of the underlying mcfedr/sqs-queue-driver library. Do not trust the bundle README alone — with 4 stars and 0 dependents, verify option names against the actual code.

Implementation Patterns

Message as a thin DTO. Keep messages small and serializable (scalars/arrays, not Eloquent/Doctrine entities). Symfony Messenger serializes to JSON by default; entities become stale IDs by the time a worker runs.

final class SendInvoice
{
    public function __construct(public string $invoiceId) {}
}

Dispatch from anywhere via the bus, not directly through the transport:

public function __construct(private MessageBusInterface $bus) {}

$this->bus->dispatch(new SendInvoice($id));

Worker lifecycle. Run messenger:consume as a managed daemon. In Laravel terms this is queue:work --daemon; Symfony already loops, so you add guardrails:

bin/console messenger:consume async_sqs --time-limit=3600 --memory-limit=256M -vv

Wrap with Supervisor (or systemd) with autorestart, and send SIGTERM for graceful shutdown — Symfony's worker finishes the in-flight message before exiting.

Environment-specific transport switching. Mirror Laravel's QUEUE_CONNECTION=sync trick: route to sync:// in dev/test and to sqs:// in prod. This keeps local development fast and avoids burning AWS calls in tests.

# config/packages/test/messenger.yaml
framework:
  messenger:
    transports:
      async_sqs: 'in-memory://'

Multiple queues for priority/isolation. Register several transports (async_sqs_high, async_sqs_low) pointing at different SQS queues, route expensive jobs to a dedicated queue, and run separate worker pools. This is how you avoid one slow job class starving everything else — the same reason you'd split Laravel queues.

Retries and failure handling. Symfony Messenger has its own retry strategy on the transport, and SQS has its own redrive policy/DLQ. Use one, not both, or you get confusing double-retry behaviour. Either let Messenger retry in-process (retry_strategy on the transport) or let SQS move messages to a DLQ after maxReceiveCount and have a separate consumer for it. Pick a single owner.

Idempotency. SQS is at-least-once. Any handler that charges a card, sends an email, or writes to an external system must be idempotent (dedup key in Redis/DB, or an upsert). This is not optional in production.

Bridging into a Laravel app. Don't try to install this bundle inside Laravel's container. If you genuinely need Symfony's worker behaviour alongside Laravel, run the Symfony console process as a separate service writing to/reading from the same SQS queue, and agree on a message envelope (JSON schema, type field, serializer compatibility) with your Laravel queue:work sqs consumers. Mixing Symfony's default serializer with Laravel's SerializesModels payload format will not work — standardise explicitly.

Observability. Hook WorkerMessageFailedEvent, WorkerMessageHandledEvent, and WorkerRunningEvent to emit metrics/logs. This is the equivalent of Laravel's queue events; it's where you add timing and alerting.

Gotchas and Tips

  • Framework mismatch is the biggest trap. This is a Symfony bundle, not a Laravel package. It cannot be dropped into a Laravel project as a queue driver. Treat any evaluation that assumes otherwise as a red flag. The only Laravel-relevant use is a worker process in a polyglot/poly-framework setup.
  • Adoption risk. 4 stars and 0 dependents is a strong signal: low bus factor, likely unmaintained, and thin community support. Before committing, check the last commit date, open issues, and whether it supports your Symfony/PHP version. Pin the version and be prepared to vendor/fork the transport factory if upstream stalls. Budget time for reading the actual source — the README may lag behind the code.
  • Visibility timeout vs. processing time. SQS redelivers a message if its visibility timeout elapses before you delete it. A long-running Symfony handler that exceeds the timeout causes duplicate execution. Set the queue's visibility timeout comfortably above your worst-case processing time, or extend it mid-flight (ChangeMessageVisibility) for long jobs.
  • IAM permissions. The worker needs sqs:ReceiveMessage, sqs:DeleteMessage, sqs:ChangeMessageVisibility, sqs:GetQueueUrl, and the producer needs sqs:SendMessage (+ sqs:GetQueueAttributes if you use queue setup). Missing ChangeMessageVisibility is a common silent failure.
  • Region/credentials resolution. The DSN, the queue's region, and the credential source must agree. On ECS/EKS prefer the IAM task role; locally use AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or a shared profile. A mismatch produces confusing "queue not found" errors rather than auth errors.
  • SQS limits. 256 KB max message size, 14-day retention, 10 messages per receive/purge batch, and FIFO queues require MessageGroupId (and dedup IDs). Keep payloads as references (IDs/paths) rather than blobs.
  • FIFO caveat. FIFO queues serialise per message group, which can silently serialise your throughput. Use them only where ordering genuinely matters, and set message group IDs deliberately.
  • Auto-setup quirks. If the driver supports creating queues/attributes on boot (auto_setup style option), leave it off in production. Queue creation in a worker startup path is a permission and race-condition hazard.
  • Serializer compatibility. If you share queues with Laravel or other services, confirm the wire format. Symfony's default JSON serializer and Laravel's PHP-serialized payloads are incompatible; agree on a serializer and envelope.
  • Debugging. Run -vv on the consumer to see dispatch/ack logs, inspect the failure transport (messenger:failed:show), and check CloudWatch NumberOfMessagesReceived / ApproximateAgeOfOldestMessage to distinguish "worker down" from "worker slow". ApproximateAgeOfOldestMessage climbing is your queue-backlog alarm.
  • Graceful shutdown and signals. Ensure your Supervisor config sends SIGTERM (not SIGKILL) so in-flight messages finish. --time-limit lets a worker exit cleanly and be restarted, which is the safest way to avoid memory leaks in long-running PHP.
  • Extension points. Customize behaviour via Messenger middleware (for tracing, idempotency, tenant context), a custom serializer, or your own transport factory that wraps the bundle's. Symfony's event dispatcher gives you the observability hooks; avoid editing vendor code — fork the transport if needed.
  • Test in isolation. Add an integration test that runs against LocalStack SQS rather than mocking the AWS client. SQS behaviours (visibility timeout, redrive, DLQ) are where most bugs live, and mocks won't reproduce them.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource