Download the PHP package gpalyan/laravel-outbox without Composer

On this page you can find all versions of the php package gpalyan/laravel-outbox. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-outbox

Laravel package implementing the Transactional Outbox / Inbox patterns. Broker-agnostic: ship messages to any transport (NATS, Kafka, RabbitMQ, SQS, HTTP webhook — anything you can call publish() on).

Contents

Delivery semantics

The package gives you at-least-once delivery to the broker plus idempotent storage on both sides keyed on a caller-supplied deduplication_key. Composed together, this is what is commonly called effectively-exactly-once:

True exactly-once delivery to a remote broker is impossible (FLP, two-generals); don't promise it. What you can promise to downstream consumers is effectively-exactly-once processing of each logical message, which is what this package implements.

The deduplication key is yours, by design. The identity of a logical message — "is this the same event or a new one?" — is domain knowledge only the caller has; the package cannot infer it and does not try. You pass an explicit deduplicationKey (e.g. order.created:42, or order.payout:42:attempt-2 when a second payout is intended). Make it stable for the same logical event and distinct for genuinely different ones.

If you want content-addressed dedup (one row per unique payload), opt in explicitly with OutboxMessage::hashPayload($payload) as the key — but note it only holds if the payload is canonical (no timestamps / random fields), otherwise duplicates hash differently and won't dedup.

Requirements

Installation

Publish config and migrations:

Configuration

Variable Default Description
OUTBOX__RETRY_BACKOFF 2 Exponential backoff multiplier
OUTBOX__RETRY_JITTER 0.2 Random jitter factor (0–1)
OUTBOX__RETRY_MAX_DELAY 86400 Max delay between publish retries (seconds)
OUTBOX__IN_PROGRESS_DEADLINE 60 Seconds before an in-progress outbox row is considered stuck
OUTBOX__PRUNE_AFTER_DAYS 30 Days to keep sent messages before pruning
INBOX__MAX_ATTEMPTS 5 Max handler invocations before permanent failure
INBOX__RETRY_DELAY_SECONDS 15 Initial retry delay
INBOX__MAX_DELAY_SECONDS 3600 Max delay between handler retries
INBOX__IN_PROGRESS_DEADLINE 300 Seconds before an in-progress inbox row is considered stuck
INBOX__PRUNE_AFTER_DAYS 30 Days to keep processed messages before pruning

Outbox — publishing messages

1. Write to the outbox inside your DB transaction

Batch insert (skips Eloquent events, useful for bulk producers). Each item is an OutboxDraft — the deduplication key is a required constructor argument, so it cannot be silently omitted for any message in the batch:

Duplicate keys inside a single batch (or against rows already stored) are skipped by the unique index — no need to pre-check the array yourself.

2. Implement OutboxPublisherInterface for your broker

Below is a complete working example using RabbitMQ via php-amqplib/php-amqplib. Replace with your broker SDK; the contract is the same: take an OutboxMessage, publish it, throw on failure.

Route table lives in your own config:

3. Bind it in the service container

4. Schedule the publisher worker

Inbox — receiving messages

1. From your broker subscriber, fire MessageConsumed

The package does not subscribe to any broker. You bring your own subscriber (a long-running artisan command, a daemon, a worker subscribed to push notifications — whatever fits your broker). For each message received, fire the package event.

A complete RabbitMQ subscriber as an artisan command:

Run one process per (queue, channel) pair under supervisor / systemd:

The package registers OnMessageConsumed to this event automatically. The listener stores the message in inbox_messages (idempotent on the deduplicationKey you supply — use the broker message id so broker re-deliveries dedup).

Synchronicity contract — important.

event(new MessageConsumed(...)) invokes the listener synchronously, in the same PHP process and call stack as your subscriber. The listener performs a DB write before event() returns. Implications:

2. Implement a handler per channel

3. Bind channel → handler in the container

The key passed to bind() must match the channel you put into MessageConsumed.

4. Schedule the inbox worker

Pruning old rows

prune_after_days in config controls the cutoff. Only successfully terminated rows are pruned — SENT on the outbox side, PROCESSED on the inbox side. FAILED rows are kept indefinitely.

Why FAILED rows are never auto-pruned

A FAILED row means the package exhausted retries and gave up. Two cases:

In both cases the row is the only surviving evidence of a lost business event. Auto-pruning it silently erases problems that need human eyes — broken routes, bad payloads, handler bugs. So the package keeps them.

How it works

Both sides use exponential backoff on failure with configurable max attempts. Stuck in-progress rows (worker crashed mid-flight) are returned to pending after the configured deadline.

Public surface

Symbol Purpose
TransactionalOutbox\Models\OutboxMessage Store outgoing messages inside your DB transaction
TransactionalOutbox\Models\InboxMessage (read-only from your code) Inbound message rows
TransactionalOutbox\Contracts\OutboxPublisherInterface Implement to publish to your broker
TransactionalOutbox\Contracts\InboxHandlerInterface Implement per channel to process inbound messages
TransactionalOutbox\Events\MessageConsumed Fire from your broker subscriber to push into the inbox
TransactionalOutbox\Events\OutboxMessageSent Dispatched after successful publish
TransactionalOutbox\Events\OutboxMessageFailed Dispatched after permanent publish failure
TransactionalOutbox\Events\InboxMessageProcessed Dispatched after successful handler invocation
TransactionalOutbox\Events\InboxMessageFailed Dispatched after permanent handler failure
Artisan: transactional-outbox:process outbox\|inbox The worker entrypoint

Client responsibilities

Responsibility Who
Provision broker (streams, topics, queues, subscriptions) You
Call OutboxMessage::store() inside DB transactions You
Supply a stable, logical deduplicationKey per message You
Implement and bind OutboxPublisherInterface You
Implement and bind InboxHandlerInterface per channel You
Run a broker subscriber that fires MessageConsumed You
Schedule transactional-outbox:process outbox and ... inbox You
Enforcing dedup on the key, storage, retries, backoff, pruning, transitions Package

All versions of laravel-outbox with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
illuminate/support Version ^12.0|^13.0
illuminate/database Version ^12.0|^13.0
illuminate/console Version ^12.0|^13.0
illuminate/queue Version ^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package gpalyan/laravel-outbox contains the following files

Loading the files please wait ...