nathanphelps / watchtower
Cross-platform Laravel queue monitoring and worker management
Fund package maintenance!
nathanphelps
Installs: 12
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
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.
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