Looking to hire Laravel developers? Try LaraJobs

laravel-queue-monitor maintained by jaydeep

Description
Monitor your Laravel queues — track pending, running, completed, and failed jobs from an Artisan command or a live web dashboard.
Last update
2026/07/10 12:45 (dev-main)
License
Links
Downloads
0

Comments
comments powered by Disqus

Laravel Queue Monitor

Monitor your Laravel queues at a glance. Laravel Queue Monitor records the full lifecycle of every queued job and shows you pending, running, completed, and failed jobs — from an Artisan command or a live web dashboard.

Laravel ships with failed_jobs (failed) and a jobs table (pending, database driver only), but it never stores completed jobs. This package fills that gap by subscribing to Laravel's queue events and persisting each job's lifecycle to a dedicated queue_monitor table — so it works with any queue driver (database, Redis, SQS, …).

Screenshots

The live dashboard with stat cards and the recent-jobs table.

Queued (pending) jobs:

Queue Monitor dashboard showing queued jobs

Completed & failed jobs:

Queue Monitor dashboard showing completed and failed jobs

Requirements

  • PHP 7.4 – 8.4
  • Laravel 8 – 12

Installation

From Packagist

composer require jaydeep/laravel-queue-monitor

Local development (path repository)

If you are working on the package from a local checkout, add a path repository to your application's composer.json before requiring it:

"repositories": [
    {
        "type": "path",
        "url": "./laravel-queue-monitor",
        "options": { "symlink": true }
    }
]
composer require jaydeep/laravel-queue-monitor:^1.0

Publish and migrate

The service provider is auto-discovered. Publish and run the migration:

php artisan vendor:publish --tag=queue-monitor-migrations
php artisan migrate

Optionally publish the config and views:

php artisan vendor:publish --tag=queue-monitor-config
php artisan vendor:publish --tag=queue-monitor-views

Usage

Artisan command

php artisan queue-monitor:show
Queue Monitor
+---------+---------+-----------+--------+-------+
| Pending | Running | Completed | Failed | Total |
+---------+---------+-----------+--------+-------+
| 3       | 1       | 128       | 2      | 134   |
+---------+---------+-----------+--------+-------+

Options:

Option Description
--json Output the full snapshot as JSON
--limit=N Number of recent jobs to list
--prune Delete records older than the configured retention hours

--json returns a machine-readable snapshot:

{
    "counts": {
        "pending": 3, "queued": 2, "running": 1,
        "completed": 128, "failed": 2, "total": 134
    },
    "recent": [
        {
            "id": 134, "name": "App\\Jobs\\SendInvoice", "queue": "default",
            "connection": "redis", "status": "completed", "attempts": 1,
            "duration_ms": 412, "queued_at": "2026-07-10 09:15:01",
            "started_at": "2026-07-10 09:15:02", "finished_at": "2026-07-10 09:15:02",
            "exception": null
        }
    ],
    "generated_at": "2026-07-10 09:20:00"
}

Web dashboard

Visit /queue-monitor in your browser for a live, auto-refreshing, responsive Bootstrap 5 dashboard with stat cards and a paginated recent jobs table (Prev / Next). It polls /queue-monitor/stats on the interval set in config; the stat cards always reflect global totals while the table is paged.

The stats endpoint accepts pagination query parameters:

GET /queue-monitor/stats?page=2&per_page=15

Response shape:

{
    "counts": { "pending": 3, "running": 1, "completed": 128, "failed": 2, "total": 134 },
    "recent": [ /* current page of jobs */ ],
    "pagination": { "current_page": 2, "per_page": 15, "total": 134, "last_page": 9, "from": 16, "to": 30 },
    "generated_at": "2026-07-10 09:20:00"
}

Security: the dashboard uses the web middleware group by default. Before exposing it in production, add authentication/authorization middleware in config/queue-monitor.php (route.middleware), e.g. ['web', 'auth'].

Configuration

config/queue-monitor.php:

Key Default Description
enabled true Master switch for lifecycle recording
table queue_monitor Monitor table name
connection null DB connection for the table (null = default)
route.enabled true Enable the web dashboard routes
route.prefix queue-monitor URL prefix for the dashboard
route.middleware ['web'] Middleware applied to the dashboard routes
route.refresh 5 Dashboard auto-refresh interval (seconds)
recent_limit 25 Recent jobs shown in the console command
per_page 15 Jobs per page on the web dashboard
prune_after_hours 72 Retention window used by --prune (null = keep)

Each key is also driven by an environment variable — set QUEUE_MONITOR_ENABLED=false to switch recording off without touching config, or QUEUE_MONITOR_ROUTE_ENABLED=false to disable the dashboard routes.

How it works

The package registers a subscriber for Laravel's queue events:

Event Recorded status
JobQueued queued
JobProcessing running
JobProcessed completed
JobFailed failed

Records are correlated by job id across events. All monitor writes are wrapped in a guard, so a monitoring error can never interrupt the job being processed.

queue_monitor table

Column Notes
id Primary key
job_id Driver job id (used to correlate events)
name Resolved job class name
connection, queue Where the job ran
status queued / running / completed / failed
attempts Attempt count at last update
queued_at, started_at, finished_at Lifecycle timestamps
duration_ms Processing time in milliseconds
exception Full exception string for failed jobs
created_at, updated_at Eloquent timestamps

Querying in code

use Jaydeep\QueueMonitor\Models\MonitoredJob;

MonitoredJob::failed()->latest()->take(10)->get();
MonitoredJob::completed()->count();
MonitoredJob::pending()->get(); // queued + running

Testing

composer install
./vendor/bin/phpunit

License

MIT © Jaydeep Gadhiya