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

Message Outbox For Illuminate Laravel Package

eventsauce/message-outbox-for-illuminate

A Laravel/Illuminate outbox for EventSauce that persists domain messages transactionally alongside your business data, then relays them to consumers, avoiding dual-write problems and helping guarantee reliable, at-least-once event delivery.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This package is the Illuminate binding for EventSauce's MessageOutbox abstraction — the transactional outbox pattern. The premise is well-understood and correct: domain messages are inserted into an outbox table inside the same database transaction that persists the aggregate, and a separate relay drains that table to a broker or queue with at-least-once semantics. It replaces the common Laravel anti-pattern of dispatching jobs inside a transaction or from model observers, where a post-commit crash silently drops messages.

The fit is strong only when two preconditions hold: the team already uses EventSauce contracts (Message, MessageDispatcher) or is willing to adopt them, and the write model and outbox share one relational database. If the team uses a different event-sourcing library, or the consumer can join the transaction, the package adds a dependency without removing a failure mode.

Integration feasibility. The package is a thin adapter, so its own surface is small — but it is not deployable on its own. Composition requires four moving parts: a published migration for the outbox table, a relay entry point (Artisan command or queue worker) running as a supervised process, a message serializer, and the downstream consumer. A TPM should treat the package as one line in a composer.json and the relay plus observability as the actual deliverable. Estimates that stop at "add the dependency" are wrong by an order of magnitude.

Technical risk. The material risks are organizational, not architectural:

  • Zero adoption signal. 0 stars and 0 dependents is not evidence of poor quality — subtree splits are systematically under-starred — but it means no public corpus of production war stories, tutorials, or Stack Overflow answers. Every integration question becomes a first-principles question.
  • Bus factor of one. The repository is a [READ ONLY] subtree split of the EventSauce monorepo with no issue tracker and no PR flow. A security or compatibility fix requires an upstream release or a fork.
  • Version drift. Tags mirror monorepo tags; Illuminate and PHP constraints are dictated upstream and are not visible from this repository.
  • Documentation fragmentation. Usage guidance lives in the EventSauce docs, not here. Expect a minimal README.

Key questions to resolve before committing:

  1. Which illuminate/* and PHP constraints are declared, and is there an explicit Laravel 11/12 support statement?
  2. Does the package ship a publishable migration and config, or is schema ownership ours?
  3. What is the reference relay implementation — Artisan command, queued job, or a dispatcher we must supply?
  4. How is concurrent relay execution handled (FOR UPDATE SKIP LOCKED, advisory locks), and is ordering guaranteed per aggregate root?
  5. Is there a retention/pruning story, or is that entirely on us?
  6. What is the upstream release cadence and stated BC policy for the split?

What this buys the roadmap. Two things worth naming explicitly to stakeholders. First, it enables a contract-level guarantee — "every confirmed order emits exactly one fulfillment event" — which is often worth more commercially than the feature itself. Second, it unblocks a class of event-driven work (partner webhooks, ledger events, read-model projection, cache invalidation) rather than a single feature. Price the alternative honestly: a competent engineer can hand-roll the shape in a day or two, and adopting the pattern without the package is a legitimate outcome.

Integration Approach

Stack fit. Best case is a Laravel application on PostgreSQL or MySQL 8+ with existing EventSauce aggregates and a queue or broker downstream (SQS, RabbitMQ, Redis). The pattern is database-agnostic, but the relay's concurrency story is materially better on Postgres, where SKIP LOCKED is native. Confirm the engine before designing the relay, not after.

Migration path. Do not big-bang this. A staged adoption:

  1. Shadow mode. Keep the existing dispatch path; additionally write to the outbox. Relay to a no-op consumer and diff against the live path to validate completeness cheaply.
  2. Cut over per bounded context. Flip one aggregate root at a time so the blast radius is one event stream.
  3. Retire the legacy path after a full clean release cycle, then drop the shadow consumer.

Compatibility. Because the split tracks monorepo tags, pin an exact version in composer.json rather than a floating constraint — an upstream release can move Illuminate constraints under you. Validate against the team's pinned Laravel and PHP versions in a throwaway branch before design work begins.

Sequencing. Roughly two to three sprints for a single bounded context, with explicit gates:

  1. Composer spike, migration publish, schema review in a scratch environment.
  2. Build and load-test the relay; decide worker topology (dedicated supervisor vs. queue-driven).
  3. Stand up observability before cutover — outbox depth, relay lag, publish-failure counter, dead-letter table.
  4. Shadow run plus reconciliation report; gate on a clean diff.
  5. Cut over one context, legacy path feature-flagged for rollback.
  6. Write the runbook, then — and only then — consider a second context.

The TPM's lever here is the gates: each phase has a defined exit criterion, and "the outbox exists" is not one of them.

Operational Impact

Maintenance. Low code volume, non-zero attention. You inherit a dependency you cannot patch locally, so every Illuminate upgrade is gated on an upstream release. Budget for a possible fork — realistically a few days a year, but catastrophic if unplanned during a framework upgrade window.

Support. No issue tracker on this repository. Support routes through the parent EventSauce project and community channels. Designate a named internal owner who reads the upstream changelog; nobody else will surface breaking changes before they land.

Scaling. The outbox table is the pressure point, on two dimensions:

  • Write volume. Every domain event is an insert competing with OLTP traffic for the same database. Plan indexing (e.g. on dispatched_at, id) and expect index maintenance overhead.
  • Relay throughput. A single-threaded relay eventually bottlenecks. Scaling to multiple workers depends on the locking strategy being correct — verify it explicitly rather than assuming.

Pruning must be automated from day one. An unpruned outbox is the most common operational failure of this pattern, and it degrades the whole application, not just the messaging path.

Failure modes to design for, with named owners:

  • Duplicate delivery. At-least-once is the contract, not a bug. Idempotent consumers are a consumer-side obligation the package cannot enforce — a frequent source of incidents.
  • Relay crash mid-publish. Messages handed to the broker but not marked dispatched get re-sent. Harmless only if consumers dedupe.
  • Stalled relay. If the supervisor dies silently, the outbox grows and consumers starve while the app looks healthy. Alerting on outbox depth and age-of-oldest-undispatched-row is mandatory.
  • Poison messages. One unconsumable message head-of-line-blocks the relay. A dead-letter/quarantine path must exist and be exercised, not just documented.
  • Long transactions. Because the outbox shares the transaction, a slow commit now holds outbox row locks. Review transaction boundaries before adoption.

Ramp-up. A mid-level Laravel engineer can wire the package in under a week. Operating it correctly — idempotency, lag alerting, pruning, dead-letter handling — is closer to two to three weeks for the on-call engineer. That operational literacy, not the composer require, is the real cost of adoption.

Bottom line. The architecture is right and the code surface is small, but this repository is a low-signal distribution artifact: 0 stars, 0 dependents, read-only split, single maintainer. Adopt the pattern; treat this package as a replaceable implementation detail. Run a single-context pilot behind the observability and pruning gates above, and keep afterCommit dispatch as the answer for any consumer that lives inside your own Laravel queue.

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/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
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route