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

Symfony Messenger Redis Laravel Package

krak/symfony-messenger-redis

Redis transport for Symfony Messenger, enabling asynchronous message dispatch and consumption through Redis. Integrates with Messenger’s transport system to support queue-based workflows in Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and check platform requirements. composer require krak/symfony-messenger-redis. The package targets Symfony Messenger 5.x/6.x — and v0.1.8 is the release that explicitly widened the constraint to cover Symfony 5, so verify the actual symfony/messenger range in composer.json rather than trusting README badges or the previous constraint. Like most Redis transports it expects the phpredis extension — confirm ext-redis is present before wiring anything. If you run Predis only, this is likely a non-starter, and Symfony 4.x is still out of scope.

  2. Registration is usually automatic. Symfony's FrameworkBundle collects anything tagged messenger.transport_factory. If you are not using full-stack Symfony (or autoconfigure is off), add the tag manually in config/services.yaml. First place to look: the package's src/ for the factory and connection classes, then the README's DSN/option table. v0.1.8 did not touch the factory or registration path — only constraints and dev dependencies — so existing wiring instructions are unchanged.

  3. Configure a transport in config/packages/messenger.yaml:

    framework:
      messenger:
        transports:
          async:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            retry_strategy:
              max_retries: 3
              delay: 1000
              multiplier: 2
        routing:
          App\Message\SendWelcomeEmail: async
    

    Set MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages (add ? options and a rediss:// variant for TLS as needed).

  4. First use case: async side effects — outbound email, webhook delivery, thumbnail generation, third-party API sync. Dispatch the message from a controller, then run bin/console messenger:consume async -vv and confirm the job is popped and acknowledged.

  5. Before you commit, read the connection class to see which Redis primitives it uses (lists vs. streams) and whether it exposes a reclaim/claim operation. That detail drives every operational decision below — and since v0.1.8 shipped no runtime changes, whatever you observe now is what you will be living with for a while.

Implementation Patterns

  • One transport per queue class. Use async for best-effort work and a separate async_priority or notifications transport with its own DSN key so a backlog in one cannot starve the other.
  • Always pair with a durable failure transport. Route failed: 'doctrine://default?queue_name=failed' (or a dedicated Redis instance with persistence and noeviction) so retries survive a Redis restart. Never let the failed queue live on a cache-role Redis.
  • Keep messages small and referential. Send IDs and scalars, not entities. This keeps serialization stable across deploys and sidesteps the "message shape changed while messages were in flight" class of bug.
  • Handlers must be idempotent. Redis-backed transports can redeliver after a worker crash between BRPOP-style pop and ack (or after an in-flight reclaim). Guard with a processed_events table, a Redis SETNX keyed on message ID, or a unique constraint.
  • Delays: use DelayStamp for scheduled work rather than sleep() in a handler. If the transport does not natively support delayed delivery, implement it as a dedicated "delayed" transport plus a cron-driven promoter, or move to Symfony Scheduler (6.3+) for time-based dispatch.
  • Consumer supervision: run workers under systemd or Supervisor with messenger:consume async --time-limit=3600 --memory-limit=128M --limit=1000. On deploy, call messenger:stop-workers so workers finish their current message and pick up new code.
  • Composition over subclassing. Decorate the SenderInterface/ReceiverInterface for cross-cutting concerns (logging, metrics, tenancy headers) rather than forking the package — with 8 stars and 0.x versioning, you want a clean seam to swap the transport later.
  • Upgrade discipline when a tag lands. Treat every release — including a constraints-only one like v0.1.8 — as a prompt to re-run composer why-not krak/symfony-messenger-redis, diff composer.json, and run your integration test against a real Redis DB index before merging the lockfile bump. A dev-dependency refresh can change nothing at runtime but still moves what CI validates against (PHPUnit/PHP matrix), so keep your own integration test as the source of truth.
  • Testing: bind MESSENGER_TRANSPORT_DSN to in-memory:// (or sync://) in config/packages/test/ for unit-level assertions, and reserve a real Redis DB index (e.g. /15) for integration tests. Flush that DB in setUp.
  • Observability: queue depth is LLEN/XLEN on the queue key (plus the processing/in-flight key); export it as a gauge. Alert on age of the oldest message, not just depth — a stalled consumer with an empty-looking queue is the failure mode that hides longest.

Gotchas and Tips

  • Maintenance risk is still the headline — but calibrate it. Eight stars, zero dependents, 0.x versioning. v0.1.8 is a narrow release: it widens support to Symfony 5 and bumps dev dependencies, with no new features, no runtime changes, and no deprecations. That is a sign of life, not of active feature development — the API surface is frozen and the transport internals are unchanged. Pin an exact version, keep the transport behind DSN configuration and interface decorators, and benchmark against symfony/redis-messenger (the first-party Redis transport, stream-based with consumer groups). Migrating later should be a DSN change plus a drain, not a rewrite.
  • Check the constraint, not the changelog. "Support Symfony 5" is ambiguous as written — confirm in composer.json whether it means symfony/messenger 5.x or full-stack Symfony 5 framework constraints, and whether the previous tag really excluded 5.x. If you already run Symfony 5 and were pinned to an older version, this is the release that unblocks you; if you are on 4.x or on Predis, nothing here changes your situation.
  • Redis is not a broker by default. Without AOF (appendfsync everysec) a restart loses queued jobs. Worse, an allkeys-lru or volatile-* eviction policy on a shared cache instance will silently evict your queues under memory pressure. Use a dedicated instance or DB with maxmemory-policy noeviction and persistence enabled.
  • In-flight recovery. Determine explicitly whether the connection acknowledges on pop or on handler success. If it uses pop-and-move-to-processing, you need a periodic claim/reclaim job for messages orphaned by a killed worker — otherwise they sit forever. If the package ships a claim command, put it on cron at a fraction of your handler timeout.
  • Blocking reads need a read timeout. phpredis BRPOP-style calls hang indefinitely unless \Redis::OPT_READ_TIMEOUT is set above zero; the Symfony worker's stop signals then never get observed. Verify the connection sets it.
  • Setup step. messenger:setup-transports only works if the transport implements SetupableTransportInterface. Check whether keys or consumer groups must be created out of band, or whether an auto_setup-style DSN option exists. Test a cold, empty Redis — that is where first deploys break. v0.1.8 did not add setup tooling, so this remains manual if it was before.
  • DSN parsing surprises. The path component is typically the queue/stream name, the trailing number a DB index, and query options are passed to the connection verbatim. Verify auth (redis://:password@host), TLS (rediss://), and prefix options against the README table rather than guessing — the release notes did not document new options, so assume the option table is unchanged.
  • Serializer lock-in. Switching between the Symfony serializer and native PHP serialization mid-flight makes older queued messages undecodable. Choose once, deploy it, then drain the queue before changing.
  • Debugging stuck jobs: inspect the processing key directly (LRANGE processing 0 -1, or XPENDING / XINFO GROUPS for streams) before reaching for MONITOR on staging. Most "lost message" reports are messages sitting in the in-flight structure awaiting reclaim.
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