Laravel Horizon and Telescope: Queue Monitoring & Debugging
Master Laravel Horizon for queue monitoring and Telescope for debugging.
20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.
- ✓Basic knowledge of Laravel queues and Redis
- ✓Laravel application with Redis configured
- ✓Composer installed
- ✓Access to a server or local environment for running commands
- Horizon provides a dashboard to monitor queues, failed jobs, and metrics.
- Telescope offers request debugging, exception tracking, and query profiling.
- Both require Redis and are configured via service providers.
- Use tags and watchers to customize Telescope's data collection.
- Production deployment needs environment-specific settings and authentication.
Imagine you run a busy restaurant kitchen. Horizon is like a manager who watches the order queue, tells you which orders are cooking, which are stuck, and how fast chefs are working. Telescope is like a security camera that records every order, every mistake, and every ingredient used, so you can replay and fix issues later.
In modern web applications, handling background tasks efficiently is crucial for performance and user experience. Laravel's queue system allows you to defer time-consuming tasks like sending emails, processing images, or generating reports. However, as your application grows, monitoring queues and debugging issues becomes a challenge. This is where Laravel Horizon and Telescope come in. Horizon provides a beautiful dashboard to monitor your queues, view metrics, and manage failed jobs. Telescope offers deep debugging capabilities, capturing requests, exceptions, queries, and more. Together, they form a powerful toolkit for maintaining and troubleshooting Laravel applications in production. In this tutorial, you'll learn how to install, configure, and use both tools effectively, with real-world examples and best practices.
Installing and Configuring Horizon
Horizon requires Redis and the predis or phpredis driver. Install via Composer: composer require laravel/horizon. Publish assets and configuration: php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider". Configure .env with QUEUE_CONNECTION=redis and REDIS_HOST=.... The config/horizon.php file allows you to define environments, balance strategies, and supervisor settings. For production, set 'environments' => ['production' => ['supervisor-1' => ['connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'processes' => 3, 'tries' => 3]]]. Use php artisan horizon to start the dashboard. Secure it with authentication middleware in HorizonServiceProvider::gate().
'balance' => 'auto' to dynamically scale workers based on queue load. Monitor memory usage to avoid OOM kills.config/horizon.php and requires Redis. Use supervisor for process management.Monitoring Queues with Horizon Dashboard
Once Horizon is running, access the dashboard at /horizon. It shows real-time metrics: jobs processed per minute, queue status, failed jobs, and worker count. You can pause, resume, or terminate queues. The 'Failed Jobs' tab lists all failed jobs with their exception messages and stack traces. You can retry or delete them. Horizon also provides a 'Metrics' section with charts for throughput and runtime. Use tags to group jobs by type (e.g., SendEmailJob). The dashboard is invaluable for spotting bottlenecks and ensuring workers are healthy.
Installing and Configuring Telescope
Telescope is a debugging companion that captures requests, exceptions, database queries, and more. Install via composer require laravel/telescope. Then run php artisan telescope:install and php artisan migrate. Publish config: php artisan vendor:publish --provider="Laravel\Telescope\TelescopeServiceProvider". In .env, set TELESCOPE_ENABLED=true for local and optionally for production. Configure watchers in config/telescope.php to enable/disable specific data collection. For production, limit data retention with 'limit' => 1000 and use the 'storage' driver (database by default). Secure the dashboard similarly to Horizon.
'size_limit' to truncate large request bodies.Debugging with Telescope: Requests, Queries, and Exceptions
Telescope's dashboard at /telescope shows a timeline of requests. Each entry includes method, URI, duration, status code, and memory usage. Click to see headers, input, session, and response. The 'Queries' tab lists all database queries with bindings and execution time, helping identify N+1 problems. The 'Exceptions' tab captures all thrown exceptions with stack traces and request context. You can filter by type or status. Telescope also logs mail, notifications, cache hits/misses, and scheduled tasks. Use the 'Search' feature to find specific entries by tag or content.
'slow' => 100 in QueryWatcher to flag queries taking over 100ms. This helps catch performance regressions early.Integrating Horizon and Telescope with Supervisor
In production, both Horizon and Telescope need to run as daemons. Use Supervisor to manage Horizon processes. Create a configuration file at /etc/supervisor/conf.d/horizon.conf with command php artisan horizon. For Telescope, no daemon is needed; it records data passively. However, ensure the queue worker (Horizon) is running to process jobs. Supervisor will restart Horizon if it crashes. Monitor Horizon's log file for errors. Telescope's data is stored in the database; schedule pruning with telescope:prune.
php artisan horizon:status to check if it's running.Advanced Features: Tags, Watchers, and Custom Data
Horizon allows tagging jobs for filtering. Telescope supports custom watchers and recording custom events. You can add tags to Telescope entries using Telescope::tag() in service providers. Create custom watchers by extending Laravel\Telescope\Watchers\Watcher. For example, a watcher to log external API calls. Use Telescope::record() to manually log entries. This is useful for monitoring third-party service interactions. Both tools support environment-specific configurations via config/horizon.php and config/telescope.php.
The Silent Queue Failure: How Horizon Saved Our Weekend
- Always monitor queue worker processes; don't rely solely on logs.
- Use Horizon's dashboard to see real-time queue status.
- Configure supervisor to restart workers automatically.
- Set up notifications for failed jobs and queue pauses.
- Test queue failure scenarios in staging before production.
php artisan horizon:terminatephp artisan horizon| File | Command / Code | Purpose |
|---|---|---|
| config | return [ | Installing and Configuring Horizon |
| app | namespace App\Jobs; | Monitoring Queues with Horizon Dashboard |
| config | return [ | Installing and Configuring Telescope |
| app | namespace App\Http\Controllers; | Debugging with Telescope |
| [program:horizon] | Integrating Horizon and Telescope with Supervisor | |
| app | namespace App\Providers; | Advanced Features |
Key takeaways
Common mistakes to avoid
4 patternsNot securing Horizon/Telescope in production
Enabling all Telescope watchers in production
Forgetting to run migrations after installing Telescope
Using Horizon without Supervisor in production
Interview Questions on This Topic
How does Horizon balance workers across queues?
Frequently Asked Questions
20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.
That's Laravel. Mark it forged?
3 min read · try the examples if you haven't