laravel-async-bus maintained by timofrenzel
Laravel Async Bus
Version: 1.0.0-rc2
Public API: DTO-only
Laravel Async Bus is a Laravel package for high-frequency asynchronous processing where ordinary one-job-per-event queues are not enough. It provides:
BufferedQueuefor deduplicated, delayed and batched state updates.ExternalQueuefor JSON job envelopes on Redis Streams, SQS or Beanstalk.- Projection Framework for rebuildable read models, search indexes and materialized views.
- Overflow spool for Redis pressure handling.
- Failed-item handling, worker/cluster visibility, metrics, dashboard and protected OpenAPI documentation.
It is not a drop-in replacement for Laravel Queue. Use Laravel Queue for ordinary background jobs. Use Async Bus when you need dedupe, batching, projection rebuilds, external workers, queue-driver abstraction or operational visibility.
Documentation
Start with:
docs/index.md- documentation map.docs/developer-guide.md- examples for Laravel developers.docs/operator-guide.md- deployment and operations.docs/configuration-reference.md- complete configuration reference.docs/module-capabilities.md- current module scope, v1 responsibilities and known gaps.docs/queues-vs-projections.md- when to use Laravel Queue, ExternalQueue, BufferedQueue or projections.docs/commands.md- Artisan command reference.docs/web-ui-verification.md- dashboard/API web-view verification record.docs/roadmap.md- v1.0 stabilization roadmap.docs/release-readiness.md- release gate and playground smoke checklist.
German introduction: README.de.md.
English introduction: README.en.md.
Choosing the right processing model
| Need | Use |
|---|---|
| Ordinary one-off PHP background job | Laravel Queue |
| Concrete JSON job that must run once | ExternalQueue |
| Many changes for the same business key should collapse | BufferedQueue |
| Rebuildable derived state/read model/search index | Projection Framework |
Short rule: ExternalQueue transports jobs. BufferedQueue collapses state changes. Projections define rebuildable derived state.
Installation
composer require timofrenzel/laravel-async-bus
php artisan vendor:publish --tag=async-bus-config
Start from the example environment:
env/async-bus.example.env
Then verify:
php artisan async-bus:config:verify
php artisan async-bus:config:audit
php artisan async-bus:docs:verify
php artisan async-bus:openapi:verify
Minimal .env
ASYNC_BUS_ENABLED=true
ASYNC_BUS_REDIS_CONNECTION=default
ASYNC_BUS_PREFIX=async_bus:
ASYNC_BUS_OVERFLOW_ENABLED=true
ASYNC_BUS_OVERFLOW_STORE=database
ASYNC_BUS_SPOOL_DB_CONNECTION=mysql
ASYNC_BUS_SPOOL_DB_TABLE=async_bus_spool_items
ASYNC_BUS_EXTERNAL_ENABLED=true
ASYNC_BUS_EXTERNAL_DRIVER=redis_streams
ASYNC_BUS_EXTERNAL_DEFAULT_QUEUE=default
ASYNC_BUS_DASHBOARD_ENABLED=true
ASYNC_BUS_DASHBOARD_ACCESS=local
ASYNC_BUS_DASHBOARD_LOCALE=de
ASYNC_BUS_API_ENABLED=false
ASYNC_BUS_API_DOCS_ENABLED=false
Full explanation of all keys: docs/configuration-reference.md.
BufferedQueue example
use TimoFrenzel\LaravelAsyncBus\BufferedQueue\Dto\BufferedUpdateDto;
use TimoFrenzel\LaravelAsyncBus\Facades\BufferedQueue;
BufferedQueue::updateDto(
BufferedUpdateDto::make('search_index', $userId)
->withPayload(['model' => 'User', 'id' => $userId])
->delay(5)
);
Use BufferedDeleteDto for deletes and BufferedPushDto for deduplicated push-style payloads.
ExternalQueue example
use TimoFrenzel\LaravelAsyncBus\ExternalQueue\Dto\ExternalJobDto;
use TimoFrenzel\LaravelAsyncBus\Facades\ExternalQueue;
ExternalQueue::dispatchDto(
ExternalJobDto::make('image.transcode', [
'image_id' => $imageId,
'source' => $path,
])->onQueue('media')
);
Projection example
use TimoFrenzel\LaravelAsyncBus\Facades\Projection;
use TimoFrenzel\LaravelAsyncBus\Projection\Dto\ProjectionUpdateDto;
use TimoFrenzel\LaravelAsyncBus\Projection\Dto\ProjectionDeleteDto;
Projection::update(ProjectionUpdateDto::make('search_index', $userId));
Projection::delete(ProjectionDeleteDto::make('search_index', $userId));
Projection handlers implement ProjectionHandlerInterface. See docs/projections.md.
Common commands
php artisan async-bus:health
php artisan async-bus:inspect
php artisan async-bus:flush search_index
php artisan async-bus:external:work default
php artisan async-bus:projection:verify
php artisan async-bus:projection:rebuild search_index --keys=1,2,3
php artisan async-bus:workers:list
php artisan async-bus:rc-audit
Dashboard and API
Dashboard:
ASYNC_BUS_DASHBOARD_ENABLED=true
ASYNC_BUS_DASHBOARD_ACCESS=local
ASYNC_BUS_DASHBOARD_PATH=async-bus
Dashboard screenshots from the local playground:
Protected API:
ASYNC_BUS_API_ENABLED=true
ASYNC_BUS_API_TOKEN=change-me
ASYNC_BUS_API_DOCS_ENABLED=false
OpenAPI files are generated and verified:
php artisan async-bus:openapi:generate
php artisan async-bus:openapi:verify
When ASYNC_BUS_API_DOCS_ENABLED=true, the protected API exposes:
GET /async-bus/api/openapi.yaml
GET /async-bus/api/openapi.json
Release checks
composer pint
composer ci
php artisan async-bus:rc-audit
The RC audit covers code, dashboard routes/views, translations, config, docs and OpenAPI drift.