nathanphelps / watchtower
Cross-platform Laravel queue monitoring and worker management
Fund package maintenance!
nathanphelps
Installs: 32
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 1
pkg:composer/nathanphelps/watchtower
Requires
- php: ^8.2
- illuminate/contracts: ^11.0|^12.0
- illuminate/database: ^11.0|^12.0
- illuminate/queue: ^11.0|^12.0
- illuminate/redis: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- symfony/process: ^6.0|^7.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
README
Cross-platform Laravel queue monitoring and worker management dashboard
Watchtower provides queue monitoring and worker management capabilities similar to Laravel Horizon, but with full cross-platform support including Windows. Unlike Horizon, which relies on PCNTL signals (Unix-only), Watchtower uses a polling-based approach for worker control that works on Windows, Linux, and macOS.
Features
- 📊 Queue Monitoring Dashboard - Real-time job tracking, status monitoring, and metrics
- ⚙️ Worker Management - Start, stop, pause, resume workers from the web UI
- 🖥️ Cross-Platform - Works on Windows, Linux, and macOS
- 📋 Job Tracking - Job status, payload, exceptions, retries, worker info
- 🎨 Modern UI - Alpine.js dark-themed dashboard (no build step required)
- 🗑️ Automatic Cleanup - Time-based pruning of old job records
Requirements
- PHP 8.2+
- Laravel 11 or 12
- Redis (for worker control commands)
Installation
composer require nathanphelps/watchtower
Publish the configuration and assets:
php artisan vendor:publish --tag=watchtower-config php artisan vendor:publish --tag=watchtower-migrations php artisan migrate
Configuration
The package configuration is published to config/watchtower.php:
return [ // Dashboard URL path 'path' => env('WATCHTOWER_PATH', 'watchtower'), // Route middleware 'middleware' => ['web'], // Authorization gate 'gate' => env('WATCHTOWER_GATE', 'viewWatchtower'), // Job retention (days) 'retention' => [ 'completed' => 7, 'failed' => 30, ], // Supervisor configuration 'supervisors' => [ 'default' => [ 'connection' => 'redis', 'queue' => '*', // Auto-discover all queues! // Or specify explicit queues: // 'queue' => ['default', 'emails', 'notifications'], 'min_processes' => 1, 'max_processes' => 10, 'tries' => 3, 'timeout' => 60, ], ], ];
Usage
Starting the Supervisor
Run the supervisor to automatically manage your queue workers:
php artisan watchtower:supervisor
The supervisor will:
- Auto-discover all queues in your application (Redis keys, job records)
- Maintain the minimum number of workers
- Restart failed workers automatically
- Monitor worker health via heartbeats
Tip: Set
'queue' => '*'in your config (default) to automatically detect and process all queues. Or specify explicit queues:'queue' => ['default', 'emails', 'high']
Manual Worker Control
Start a single worker manually:
php artisan watchtower:worker default
Zero-Downtime Deployments
Gracefully restart all workers after deploying new code:
php artisan watchtower:restart
Options:
--queue=emails- Only restart workers on a specific queue--force- Force immediate restart (don't wait for current job)
Workers will finish processing their current job, then restart with fresh code.
Terminating All Processes
Stop the supervisor and all workers (similar to horizon:terminate):
php artisan watchtower:terminate
Options:
--wait- Wait for all workers to finish before returning
Accessing the Dashboard
Visit /watchtower in your browser. By default, the dashboard is only accessible in local environments. Configure the gate in your AuthServiceProvider for production:
Gate::define('viewWatchtower', function ($user) { return in_array($user->email, [ 'admin@example.com', ]); });
Pruning Old Jobs
Watchtower automatically prunes old job records. You can also run the prune command manually:
php artisan watchtower:prune
How It Works
Polling-Based Control
Unlike Horizon which uses PCNTL signals (Unix-only), Watchtower uses Redis for worker control:
- Dashboard sends command to Redis:
SET watchtower:worker:{id}:command "stop" - Worker checks Redis every 3 seconds
- Worker reads and executes the command
- Worker confirms status in database
This approach provides:
- ✅ Cross-platform compatibility
- ✅ No PCNTL dependency
- ✅ Simple debugging
- ⚠️ 1-3 second response delay (acceptable for worker management)
Dashboard Updates
The dashboard polls for updates every 3 seconds (configurable). This provides near-real-time visibility into:
- Job counts and status
- Worker health and activity
- Throughput metrics
Artisan Commands
| Command | Description |
|---|---|
watchtower:supervisor |
Start the supervisor to manage workers |
watchtower:worker {queue} |
Start a single worker process |
watchtower:prune |
Prune old job records |
License
MIT License. See LICENSE.md for details.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
Security
If you discover a security vulnerability, please send an email instead of using the issue tracker. See SECURITY.md for details.
Credits
- Nathan Phelps
- Claude Code - AI pair programming assistant
- All Contributors