PHPackages                             ojbaeza/station - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. ojbaeza/station

ActiveLibrary[Caching](/categories/caching)

ojbaeza/station
===============

A comprehensive Laravel queue management package with multi-driver support (RabbitMQ, Redis, SQS, Beanstalkd, Kafka), job recovery, and real-time dashboard

v0.1.2(2mo ago)534[1 PRs](https://github.com/ojbaeza/station/pulls)MITPHPPHP ^8.3CI passing

Since Feb 17Pushed 1mo agoCompare

[ Source](https://github.com/ojbaeza/station)[ Packagist](https://packagist.org/packages/ojbaeza/station)[ Docs](https://github.com/ojbaeza/station)[ GitHub Sponsors](https://github.com/sponsors/ojbaeza)[ RSS](/packages/ojbaeza-station/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (15)Versions (6)Used By (0)

Station
=======

[](#station)

[![CI](https://github.com/ojbaeza/station/workflows/CI/badge.svg)](https://github.com/ojbaeza/station/actions)[![Coverage](https://camo.githubusercontent.com/e4346cf927b8be327a94c46f626a4d3248fdb8a369a57bec2154201a15036a4e/68747470733a2f2f636f6465636f762e696f2f67682f6f6a6261657a612f73746174696f6e2f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/ojbaeza/station)[![Latest Version](https://camo.githubusercontent.com/bc4d2b42593257b9f9e97ebff6d77c18121b879b8f649ff26131a793af5262e1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6a6261657a612f73746174696f6e2e737667)](https://packagist.org/packages/ojbaeza/station)[![License](https://camo.githubusercontent.com/c48128cc953429678d94403fd2b0c249de99f0b80b8f433772fe8d9f7dda0df1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6f6a6261657a612f73746174696f6e)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/88c950bb8d16d7185e01cf47aff34647ca542b508ff332c630d0106e5dd8aabe/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6f6a6261657a612f73746174696f6e2e737667)](composer.json)

**A Laravel Horizon alternative with multi-driver support and enhanced job recovery.**

Station replaces Horizon as your queue management and monitoring layer. Your existing Laravel queue code works unchanged — the only difference is running `php artisan station:work` instead of `php artisan horizon`.

Station hooks into Laravel's queue event system to transparently track every job, batch, and workflow through a real-time dashboard.

**Resources:** [Contributing](CONTRIBUTING.md) | [Security Policy](SECURITY.md) | [Changelog](CHANGELOG.md) | [Upgrade Guide](UPGRADE.md)

[![Dashboard](docs/screenshots/dashboard.png)](docs/screenshots/dashboard.png)

[![Dashboard Light](docs/screenshots/dashboard-light.png)](docs/screenshots/dashboard-light.png)

---

What Station Provides
---------------------

[](#what-station-provides)

- **Multi-driver support** — RabbitMQ, Redis, SQS, Beanstalkd, Kafka
- **Seamless job tracking** — Every `dispatch()` call is recorded automatically
- **Batch monitoring** — Real-time progress for `Bus::batch()` with integer failure thresholds
- **Workflow engine** — Multi-step DAG workflows with conditions, branching, and pause/resume
- **Job recovery** — Checkpointing for long-running jobs, stuck job detection, automatic recovery
- **Real-time dashboard** — Inertia.js + Vue 3 UI with 3-second auto-refresh
- **Built-in observability** — Prometheus metrics, health checks, multi-channel alerting (Slack, Discord, Teams, email, webhooks)
- **Alerting** — Configurable alert rules with multi-channel notifications (Slack, Discord, Teams, email, webhooks, log)
- **Security** — Job encryption, payload masking, audit logging, gate-based authorization

For a detailed comparison with Horizon, see [Station vs Horizon](docs/architecture.md#station-vs-horizon).

---

Requirements
------------

[](#requirements)

- PHP 8.3+ (8.4 recommended)
- Laravel 11.x or 12.x
- ext-pcntl, ext-posix

**Driver-specific:** ext-amqp (RabbitMQ), ext-redis or predis (Redis), aws/aws-sdk-php (SQS), pda/pheanstalk (Beanstalkd), ext-rdkafka (Kafka)

**Dashboard:** inertiajs/inertia-laravel (optional — required only for the web dashboard)

---

Installation
------------

[](#installation)

```
composer require ojbaeza/station
php artisan vendor:publish --provider="Station\StationServiceProvider"
php artisan migrate
php artisan station:install
```

Set your queue connection in `.env`:

```
QUEUE_CONNECTION=station
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_USER=your-rabbitmq-username
RABBITMQ_PASSWORD=your-secure-password
RABBITMQ_VHOST=/
```

Start the supervisor:

```
php artisan station:work
```

Access the dashboard at `/station`.

---

Jobs
----

[](#jobs)

[![Jobs](docs/screenshots/jobs.png)](docs/screenshots/jobs.png)

Standard Laravel dispatch is tracked automatically — no code changes needed:

```
// All of these are tracked by Station
ProcessOrderJob::dispatch($order);
ProcessOrderJob::dispatch($order)->onQueue('high');
ProcessOrderJob::dispatch($order)->delay(now()->addMinutes(5));
```

Station also provides a fluent API with tags and priority:

```
use Station\Facades\Station;

Station::job(new ProcessOrderJob($order))
    ->onQueue('high')
    ->delay(now()->addMinutes(5))
    ->tags(['orders', 'payments'])
    ->dispatch();
```

Station records processing time, memory usage, attempts, wait time, and status for every job.

---

Batches
-------

[](#batches)

[![Batches](docs/screenshots/batches.png)](docs/screenshots/batches.png)

Station wraps Laravel's native `Bus::batch()` with enhanced tracking. Jobs must use the `Batchable` trait:

```
use Illuminate\Bus\Batchable;

class ProcessOrderJob implements ShouldQueue
{
    use Batchable, Dispatchable, InteractsWithQueue, Queueable;

    public function handle(): void
    {
        if ($this->batch()?->cancelled()) {
            return;
        }

        // Do work...
    }
}
```

Create and monitor batches:

```
use Station\Facades\Batch;

$batch = Batch::create(
    jobs: [
        new ProcessOrderJob($order1),
        new ProcessOrderJob($order2),
        new ProcessOrderJob($order3),
    ],
    name: 'Daily Orders',
    allowedFailures: 2,  // Allow up to 2 jobs to fail (integer, not boolean)
);

// Check progress
$batch = Batch::find($batch->id);
$batch->progress();    // Percentage (0-100)

// Operations
Batch::cancel($batch->id);         // Cancel remaining jobs
Batch::retryFailed($batch->id);    // Retry failed jobs
```

For details on the overlay table strategy and atomic counter tracking, see [Batches Architecture](docs/architecture.md#batches).

---

Workflows
---------

[](#workflows)

[![Workflows](docs/screenshots/workflows.png)](docs/screenshots/workflows.png)

### Simple Workflows

[](#simple-workflows)

A DAG wrapper around `Bus::batch()` — define steps with dependencies, Station resolves execution order:

```
use Station\Core\Workflow;

Workflow::create('order-pipeline')
    ->add('validate', new ValidateOrderJob($order))
    ->add('payment', new ProcessPaymentJob($order), ['validate'])
    ->add('inventory', new ReserveInventoryJob($order), ['validate'])
    ->add('ship', new ShipOrderJob($order), ['payment', 'inventory'])
    ->onQueue('high')
    ->dispatch();
```

Steps with no dependencies between them run in parallel.

### Full Workflow Engine

[](#full-workflow-engine)

Persistent workflows with conditional steps, branching, and pause/resume:

```
use Station\Facades\Workflow;

// Define a reusable workflow
Workflow::define('payment-processing')
    ->addStep('validate', ValidatePaymentJob::class)
    ->addStep('charge', ChargeCardJob::class, ['validate'])
    ->addConditionalStep('notify',
        SendNotificationJob::class,
        fn($context) => $context['charge_successful'] ?? false,
        ['charge']
    )
    ->timeout(3600);

// Run synchronously
$instance = Workflow::run('payment-processing', [
    'amount' => 99.99,
    'user_id' => 42,
]);

// Or run asynchronously (recommended for production)
$instance = Workflow::runAsync('payment-processing', [
    'amount' => 99.99,
    'user_id' => 42,
]);
```

Workflow instances are stored in the database with full state tracking, and can be paused, resumed, or cancelled from the dashboard.

For details on execution model, branching, and context propagation, see [Workflows Architecture](docs/architecture.md#workflows).

[![Workflow Definitions](docs/screenshots/workflow-definitions.png)](docs/screenshots/workflow-definitions.png)

### Workflows vs Laravel Bus

[](#workflows-vs-laravel-bus)

Station's workflow engine provides DAG orchestration beyond what Laravel's built-in `Bus::batch()` and `Bus::chain()` can express:

FeatureStation WorkflowsBus::batch()Bus::chain()DAG dependenciesYesNoNo (linear only)Parallel executionYes (async)YesNoConditional stepsYes (runtime)NoNoDynamic branchingYesNoNoPause / ResumeYesNoNoContext passing between stepsYesNoNoPer-step status trackingYesBatch-level onlyNoPer-step retry / timeoutYes (async)Per-jobPer-jobProgress trackingYes (step %)Yes (job count %)NoCancellationYesYesStops chainStuck step recoveryYesNoNoPersisted stateYes (DB)Yes (job\_batches)NoStation workflows support both synchronous (`Workflow::run()`) and asynchronous (`Workflow::runAsync()`) execution. In async mode, each step is dispatched as a standard `ShouldQueue` job processed by Laravel workers, enabling true parallel execution across multiple workers. The orchestration layer (dependency resolution, conditional evaluation, context propagation) is where Station adds value on top of Laravel's primitives.

---

Job Recovery
------------

[](#job-recovery)

### Checkpointing

[](#checkpointing)

Long-running jobs can save progress and resume after failures:

```
use Station\Contracts\Checkpointable;

class ImportUsersJob implements ShouldQueue, Checkpointable
{
    private int $lastId = 0;

    public function handle(): void
    {
        User::where('id', '>', $this->lastId)->orderBy('id')
            ->chunk(100, function ($users) {
                foreach ($users as $user) {
                    $this->processUser($user);
                }
                $this->lastId = $users->last()->id;
            });
    }

    public function checkpoint(): array
    {
        return ['last_id' => $this->lastId];
    }

    public function restore(array $data): void
    {
        $this->lastId = $data['last_id'] ?? 0;
    }

    public function hasMoreWork(): bool
    {
        return User::where('id', '>', $this->lastId)->exists();
    }
}
```

### Stuck Job Detection

[](#stuck-job-detection)

Station detects hung jobs using weighted scoring (heartbeat, runtime, memory, process state) and can recover them automatically:

```
php artisan station:recover
php artisan station:recover --dry-run        # Preview without acting
php artisan station:recover --strategy=graceful --workflows
```

For details on scoring, strategies, and health checks, see [Recovery System](docs/architecture.md#recovery-system).

---

Artisan Commands
----------------

[](#artisan-commands)

CommandDescription`station:work`Start the supervisor (manages multiple workers)`station:status`Show queue and worker status`station:pause {queue}`Pause processing for a specific queue`station:resume {queue}`Resume a paused queue`station:terminate`Gracefully stop all workers`station:recover`Detect and recover stuck jobs (`--strategy`, `--threshold`, `--dry-run`, `--workflows`)`station:retry {id}`Retry a failed job (`--all` for all)`station:failed`List failed jobs`station:flush`Delete all failed jobs`station:prune`Clean up old data`station:health`Run health checks`station:install`Install Station`station:publish-supervisor`Generate a Supervisor config file (`--workers`, `--user`, `--path`)`station:alerts:check`Evaluate alert rules and send notifications (`--seed` to seed from config)---

Dashboard
---------

[](#dashboard)

Real-time monitoring UI at `/station` with auto-refresh every 3 seconds:

[![Connections](docs/screenshots/connections.png)](docs/screenshots/connections.png)

- **Overview** — Job throughput, failure rate, average processing time, active workers
- **Jobs** — Paginated list with status/queue/class filters, retry and delete actions
- **Failed Jobs** — Exception details, retry individually or in bulk
- **Batches** — Progress bars, status tracking, cancel and retry
- **Workflows** — Definitions, running instances, step-by-step progress
- **Monitoring** — Queue depths, worker counts, throughput charts
- **Metrics** — Historical data with time range selection

[![Metrics](docs/screenshots/metrics.png)](docs/screenshots/metrics.png)

### Authorization

[](#authorization)

By default, the dashboard is accessible in `local` environment. In other environments, configure the `authorization` gate in `config/station.php`:

```
// config/station.php
'dashboard' => [
    'authorization' => 'viewStation', // Gate name to check
],
```

Then define the gate in your `AuthServiceProvider`:

```
Gate::define('viewStation', function ($user) {
    return in_array($user->email, ['admin@example.com']);
});
```

### API

[](#api)

Full REST API at `/api/station/` (configurable) with Bearer token auth. See [`docs/openapi.yaml`](docs/openapi.yaml) for the OpenAPI 3.1 specification.

---

Configuration
-------------

[](#configuration)

```
// config/station.php (key sections)
return [
    'default' => 'rabbitmq',

    'connections' => [
        'rabbitmq' => [
            'driver' => 'rabbitmq',
            'hosts' => [[ 'host' => env('RABBITMQ_HOST', 'localhost'), /* ... */ ]],
        ],
    ],

    'supervisors' => [
        'default' => [
            'queues' => ['default'],
            'processes' => 2,
            'timeout' => 60,
            'memory' => 128,
        ],
    ],

    'dashboard' => ['enabled' => true, 'path' => 'station', 'middleware' => ['web', 'auth']],
    'recovery' => ['enabled' => true, 'stuck_job_timeout' => 900, 'auto_resume' => true],
    'checkpoints' => ['enabled' => true, 'storage' => 'database'],
];
```

For the full configuration reference, see [Configuration](docs/configuration.md).

---

Documentation
-------------

[](#documentation)

For in-depth documentation, see the [`docs/`](docs/) directory:

- **[Architecture](docs/architecture.md)** — Internal architecture: jobs, batches, workflows, workers, recovery, metrics, database schema, Station vs Horizon
- **[Queue Drivers](docs/drivers.md)** — Feature matrix, per-driver configs, known limitations
- **[Facades](docs/facades.md)** — All 7 facades with every public method
- **[Security &amp; Resilience](docs/security.md)** — API auth, encryption, masking, alerting, circuit breaker
- **[Configuration](docs/configuration.md)** — Full config reference and environment variables
- **[Migrating from Horizon](docs/migration.md)** — Step-by-step migration guide and feature mapping
- **[API Reference](docs/openapi.yaml)** — OpenAPI 3.1 specification

---

Development Setup
-----------------

[](#development-setup)

Station includes a Docker environment with all queue drivers pre-configured:

```
docker compose up -d     # Start all services
make test                # Run tests
make quality             # Run all quality checks (tests + PHPStan + code style)
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development guide, [`docker/README.md`](docker/README.md) for Docker environment details, and the `Makefile` for all available commands.

---

Contributing
------------

[](#contributing)

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code style guidelines (PER-CS 3.0), and testing requirements (95% coverage).

Security
--------

[](#security)

For security vulnerabilities, please see [SECURITY.md](SECURITY.md). **Do not** report security issues via GitHub Issues.

License
-------

[](#license)

Station is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance87

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

3

Last Release

82d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/770003?v=4)[Óscar J. Baeza](/maintainers/ojbaeza)[@ojbaeza](https://github.com/ojbaeza)

---

Tags

batch-processingbeanstalkddashboardjob-monitoringjob-queuejob-recoverykafkalaravellaravel-horizon-alternativelaravel-packagemulti-driverqueuequeue-workersrabbitmqredissqsworkflow-enginelaravelredisqueuejobrabbitmqbeanstalkdsqsdashboardworkerhorizonsupervisorkafka

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ojbaeza-station/health.svg)

```
[![Health](https://phpackages.com/badges/ojbaeza-station/health.svg)](https://phpackages.com/packages/ojbaeza-station)
```

###  Alternatives

[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.1k84.2M225](/packages/laravel-horizon)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k49.4M479](/packages/laravel-scout)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[yangusik/laravel-balanced-queue

Laravel queue management with load balancing between partitions (user groups)

786.4k](/packages/yangusik-laravel-balanced-queue)[enqueue/magento2-enqueue

Message Queue solutions for Magento2. Supports RabbitMQ, AMQP, STOMP, Amazon SQS, Kafka, Redis, Google PubSub, Gearman, Beanstalk, Google PubSub

4918.8k](/packages/enqueue-magento2-enqueue)[pdffiller/qless-php

PHP Bindings for qless

29113.2k1](/packages/pdffiller-qless-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
