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.
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.
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.
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).
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.
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.
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.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.processed_events table, a Redis SETNX keyed on message ID, or a unique constraint.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.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.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.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.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.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.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.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.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.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.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.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.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.How can I help you explore Laravel packages today?