bschmitt/laravel-amqp
Laravel AMQP is a wrapper for RabbitMQ that makes it easy to publish and consume messages from Laravel apps. Configure connections, exchanges, and queues; publish payloads; and run consumers or listeners with a clean facade and Artisan commands.
Verdict (updated for v3.4.2): v3.4.2 is a no-op for the adoption programme — it changes a Docker test-fixture base image (php:8.2.35-fpm) to clear two CVEs in dev containers only. It ships no runtime code, no public surface change, no deprecation, and no behaviour change. The previous verdict on 3.4.1 stands unchanged: the package graduated from an AMQP client wrapper into a microservice toolkit inside a patch bump, and that remains both the adoption opportunity and the governance problem.
The release does, however, change our confidence in the release process, in two ways:
3.4.x line is actively maintained rather than abandoned after the big 3.4.1 drop. That partially answers an open question from the prior assessment (security disclosure process).v3.4.2, but the Full Changelog link compares v3.4.5...v3.4.6. Either the notes were copied from a later release, the tag was re-pointed, or releases 3.4.3–3.4.6 exist and we have not reviewed them. This is the second release-hygiene defect in two releases (the first being a toolkit delivered as a patch), and it has direct supply-chain implications: we currently cannot assert which commit v3.4.2 resolves to, nor that we have reviewed every version our constraint allows us to install.Architecture fit — unchanged from the 3.4.1 assessment.
| Dimension | Assessment |
|---|---|
| Layering | Good. gRPC-lite is a thin abstraction over the existing Request/Consumer::reply() primitive — no new brokers, runtime deps, or sidecar. The platform layer (sagas, retries, DLQ, message store) sits above Amqp and is opt-in. |
| Paradigm | Aligns with Laravel idioms: facades (Rpc, Saga), container-resolvable handlers, an Artisan command, a config flag for the event bridge. Low conceptual friction. |
| Scope creep | High. Service discovery, sagas, CQRS-ish MessageStore, causation tracing, metrics, and an event bridge in one release means the package now owns concerns typically served by separate products. Any can rot independently. |
| Coupling | TypedMessage::dispatch* resolves the Amqp singleton from the container and throws outside Laravel — acceptable, but hard-codes framework coupling into the message contract layer. |
Integration feasibility — unchanged. No new Composer surface, extensions, or sidecars; everything rides the existing RabbitMQ topology. Backwards-compatibility claims remain concrete and testable. The non-trivial integration item remains the Management API dependency in DeadLetterManager::count()/messages() and MonitoringDashboard: a new network path and credential requirement from web/worker tiers to the broker's management plugin — a security review item, not a code review item. v3.4.2 does not touch this path.
Technical risk (ordered; item 0 is new)
v3.4.2 tag does not match its own changelog range (v3.4.5...v3.4.6). Until resolved we cannot state what code we are installing, nor rule out that 3.4.3–3.4.6 carry changes we have not assessed. Compounded by the fact that a ~3.4.0 or ^3.4 constraint would pull those versions silently.^3.4 receive ~13 new capability areas, two auto-registered facades, a new Artisan command, and a new config key without a deliberate upgrade decision. 3.4.2 reinforces the pattern: a patch bump is being used as a general-purpose release channel.#[Retry] is parsed as a comment on PHP 7.x — a retry policy written on 7.4 yields silently zero retries. Still the most dangerous documented behaviour in the package.InMemoryMessageStore as default. Auto-records every publish/consume into process memory: unbounded growth in long-running workers, silent data loss across restart.RpcTimeoutException vs RpcException gives useful branching, but no stated idempotency, delivery guarantee, reply-queue lifecycle, or _rpc_error envelope behaviour across trust boundaries.methods(), responseClass(), RetryPolicy::fromAttribute) surfaces drift at runtime, not build time.3.4.1 release notes remain truncated mid-class-name (ServiceCall...). 3.4.2 does not reissue them.3.4.2 is to the test fixture, which is a weak signal about production-path investment.Key questions (new items marked ✚)
v3.4.2 resolve to, and why does its changelog diff v3.4.5...v3.4.6?3.4.3–3.4.6 exist? If so we need notes for each before any constraint change.CVE-2026-109618 / CVE-2026-109619 scoped strictly to the dev container image, with no published image or runtime artefact from this project affected?3.4.1/3.4.2 version numbering deliberate? Will the maintainer re-version the toolkit drop as 3.5.0/4.0.0, or publish a feature-gate note?3.4.1 release notes and an explicit list of anything deprecated or changed in behaviour?Rpc::call()? What happens to a reply arriving after RpcTimeoutException?_rpc_error propagate raw exception messages/stack context across service or trust boundaries?InMemoryMessageStore, and is setMessageStore() attach-time or per-call?AmqpEventListener capture all Laravel events when enabled, or only marked ones? Payload serialisation and size cap?3.4.2), and is there an LTS/backport policy for the 8.x–13.x matrix?Stack fit — unchanged and still strong: Laravel 8–13, PHP 7.3–8.5, PHPUnit matrix aligned. One dependency can serve older and newer services during transition, and it is a genuine fit for teams on RabbitMQ wanting RPC, retries, and DLQ tooling without gRPC infrastructure or a separate orchestrator.
Caveats unchanged:
#[Retry] trap. Recommend we set our own floor at PHP 8.1+.v3.4.2 adds no fit considerations — it is a dev-fixture bump. Take it or skip it; do not treat it as a milestone.
Migration path — still none. Existing publish/consume code, handler signatures, config layout, and the 3.4.0 public surface are unchanged; new features are opt-in and the event bridge is off by default. 3.4.2 does not alter this. The only "migration" teams face is learning and choosing, not changing code — still the strongest property of the 3.4.x line and the headline for internal comms.
Compatibility
| Item | Position |
|---|---|
| PHP matrix | 7.3–8.5 supported; standardise on 8.1+, treat 7.x as unsupported-for-new-features |
| Laravel | 8.x–13.x + Lumen 8.x — matches fleet |
| PHPUnit | ^9.6 on 7.3/7.4, `^10.5 |
| New runtime deps | None |
| New infra deps | RabbitMQ Management API (optional, for DLQ inspection and dashboard) |
| New config | amqp.broadcast_laravel_events (default off) |
| New auto-registered | Rpc and Saga facades, amqp:monitor command |
v3.4.2 delta |
Dev-container base image only. No runtime, config, or API change. |
Sequencing — four gated phases retained; the 3.4.2 delta is folded into Phase 0. Do not let the "patch release" framing collapse this into a single upgrade ticket.
| Phase | Scope | Gate to exit | Owner |
|---|---|---|---|
| 0 — Pin & verify (expanded) | Pin exact versions fleet-wide (not ~3.4.0 — see Operational Impact); obtain full untruncated 3.4.1 notes; resolve v3.4.2 tag↔changelog discrepancy and enumerate any 3.4.3–3.4.6 releases; run the full suite on a throwaway branch; confirm nothing in the truncated surface list is a removal; confirm the two CVEs are dev-container-scoped |
Provable tag→commit mapping for every version we may install; complete notes; CI green on all supported combos | Platform eng + Security |
| 1 — Zero-behaviour upgrade | Upgrade to a verified 3.4.x fleet-wide with no new features used. Event bridge off, no message store, no RPC. |
Two weeks clean in production; no regression in publish/consume latency or error rates | SRE |
| 2 — Observability first | Enable amqp:monitor + MonitoringDashboard + CorrelationContext::setCausation()/inheritFromMessage(). Wire DLQ counts into alerting. |
Dashboards live; on-call trained on causation-id lookup | SRE + TPM |
| 3 — Reliability | Adopt RetryPolicy/#[Retry] on PHP 8+ workers only; DeadLetterManager replay/purge runbooks. Hard lint rule: #[Retry] forbidden below PHP 8. |
Runbook written and rehearsed; lint rule merged | Service teams |
| 4 — Pilot patterns | One greenfield service pair uses gRPC-lite RPC + service discovery; one workflow uses Saga with compensate(). |
Pilot retro; decision on standardisation | TPM |
MessageStore and the async Laravel event bridge remain Phase 5+, demand-driven. Ship InMemoryMessageStore only in tests; production use requires a durable backend implemented against MessageStoreInterface first. The event bridge needs data-classification sign-off before opt-in — a wildcard listener serialising Laravel events to a broker is a data-egress surface.
Maintenance
3.4.2). The prior recommendation of ~3.4.0 is withdrawn pending provenance resolution: with a tag/changelog mismatch on record, a range constraint can silently install unreviewed versions. Pin exact (3.4.1 or a verified 3.4.2) for all services not actively piloting new features; move to a range only after Phase 0 clears.laravel-amqp release gets a tag↔changelog sanity check before it can enter the fleet. This is cheap and catches exactly the class of defect 3.4.2 exhibits.Amqp::rpcDispatcher(), Amqp::dashboard()) overlap, to avoid a fragmented codebase.3.4.2 release adds no surface but also adds no documentation, runbooks, or examples — the enablement debt from 3.4.1 is entirely still outstanding.Support
amqp:monitor --json scrape target added to the monitoring estate.amqp:monitor --json remains the primary integration point for the existing observability stack — prefer it over bespoke dashboards._rpc_error remote-exception exposure, (c) event-bridge payload classification. (d) new: confirm the two CVEs are confined to dev tooling and that no published artefact of this package or its images is affected.3.4.2 CVE fix is evidence that someone responds to security items, but not evidence of an SLA, a disclosure policy, or a backport commitment. Establish contact before Phase 3, when this becomes load-bearing infrastructure.Scaling — unchanged by 3.4.2.
Rpc::call() blocks a worker for up to defaultTimeout. Bound the timeout explicitly and globally (Rpc::defaultTimeout()) and size worker pools on worst-case blocking, not average.MonitoringDashboard fans out to the Management API; with many queues polled from many replicas this can load the management plugin. Scrape from one place (a single scheduled amqp:monitor) rather than per-replica.MessageStore is ever attached fleet-wide, throughput and storage become first-class capacity concerns — every publish and consume becomes an extra write. Largest hidden cost in the release; must not be on by default.ServiceRegistry::autodiscover() implies a startup scan of RpcService subclasses; verify boot-time cost at scale before relying on alias-based discovery.Failure modes
| Failure | Symptom | Mitigation |
|---|---|---|
| Tag/changelog mismatch (new) | We install a version we cannot map to a reviewed commit; unreviewed 3.4.3–3.4.6 may exist |
Exact pinning; tag→commit verification in Phase 0; release-watch check on every upgrade |
#[Retry] on PHP 7.x |
Silent zero retries — no error, no log | Lint rule + review checklist; ban attribute below PHP 8 |
RpcTimeoutException vs. late reply |
Orphaned replies, duplicate processing | Mandate idempotent handlers; document timeout semantics; discard late replies |
InMemoryMessageStore in a worker |
Unbounded memory growth; data lost on restart | Test-only policy; enforce via config review |
| Management API unreachable | DLQ inspection and dashboard fail; replay/purge still work | Alert on scrape failure; document graceful degradation |
| Saga compensation not run | Partial state after a failed step | Require compensate() on every step(); merge-blocking review check |
| Event bridge enabled broadly | Unintended event egress, broker flooding | Keep broadcast_laravel_events false org-wide; per-app opt-in with classification sign-off |
3.4.1 notes still truncated |
Unknown removals/deprecations | Phase 0 gate — do not proceed without the full surface list |
We still cannot assert "no deprecations" for 3.4.1, and we now additionally cannot assert "all versions in range reviewed." Both remain open failure modes.
Ramp-up — cost estimate unchanged; one small reallocation.
amqp:monitor and DeadLetterManager. Everything else documented but not promoted. v3.4.2 earns no recipe.3.4.x questions through them to build a single internal knowledge base.v3.4.2 is housekeeping and requires no action beyond the pin tightening. It is not a signal to accelerate. The Phase 0 gate remains open on the 3.4.1 notes and now also on version provenance.How can I help you explore Laravel packages today?