Today I’m proud to announce Laravel Horizon, which combines a beautiful dashboard and code-driven configuration system for your Laravel Redis queues.
In addition to a brand-new, code-driven configuration system, Horizon is a truly beautiful dashboard UI, and it’s totally open source and free for entire Laravel community. We’re launching the beta tomorrow. I hope you love it.
The Horizon dashboard is a beautiful, single-page Vue application that installs directly into your existing application with a simple
composer require laravel/horizon. It provides real-time insight into queue workloads, recent jobs, failed jobs, job retries, throughput and runtime metrics, and process counts. Authentication to the dashboard is controlled by a simple callback registered via
Horizon::auth, allowing you full control over access to the dashboard.
Horizon is a wonderful new way to configure your Laravel queues. Similar to Laravel’s scheduler, all of your queue worker configuration lives in your code:
Having this configuration in your code base means it’s all under source control, making it simple for your team to collaborate. In the
config/horizon.php file, I can configure how many processes I want to create, which queues should be processed, queue timeouts, and any of the other settings I would normally pass to the
queue:work Artisan command.
Then, to start all of my queue workers, I only need a single, simple command:
php artisan horizon. No other command-line options are required. This command will read the Horizon configuration and provision all of the necessary worker processes.
Once Horizon is installed and deployed to production, you can modify your entire worker configuration by modifying your configuration file and re-deploying.
Horizon provides a clear, detailed interface for reviewing and retrying your failed jobs (yeah, we all have them). You can view the exception stack trace, tags, and recent retries for the job. It’s truly wonderful to have the recent job retries displayed directly on the failed job detail page. Because retries are linked to the original failed job, you no longer need to blindly fire
queue:retry into your console and try to figure out if the retry finishes successfully or fails again:
Horizon allows you to assign “tags” to jobs, including mailables, broadcasts, notifications, and queued listeners. In fact, Horizon will intelligently and automatically tag most jobs depending on the Eloquent models that are attached to the job.
You may easily search your jobs via these tags, allowing you to review all of the jobs for a given customer or other entity within your application. This feature allows you to quickly keep an eye on a high-value customer or find the failed job for a customer who just filed a support ticket:
Horizon can automatically balance your queue worker processes across your queues depending on the workload of those queues. For example, if your “default” queue is empty, but your “notifications” queue is swamped with jobs, Horizon can automatically allocate spare workers to your “notifications” queue to help those jobs get processed quickly.
Once the queue has caught up, Horizon will make sure the processes are re-distributed fairly across all queues.
Horizon provides throughput and average runtime charts, allowing you to see throughput and runtime trends for an individual job or for an entire queue. These metrics snapshot are captured using the
horizon:snapshot command, which can be scheduled to run as often as every minute using Laravel’s built-in scheduler. This allows you to quickly find performance degradations after a deployment.
Horizon sends both Slack and SMS notifications when one of your queues is too full. You can easily configure wait time thresholds to determine when a notification should be sent. This means you are always aware of when your queues need more workers. Once you get the notification, Horizon’s code-driven configuration allows you to make a quick configuration change to add more workers.
Conclusion & Thanks
I would like to give a special thanks to Mohamed Said, David Hemphill, and Steve Schoger, who all contributed to Horizon’s design and development. Steve designed the user interface, David Hemphill implemented the interface as a single page Vue application, and Mohamed connected the front-end to the Horizon back-end that I implemented.