Home PHP Laravel Horizon and Telescope: Queue Monitoring & Debugging
Advanced 3 min · July 13, 2026

Laravel Horizon and Telescope: Queue Monitoring & Debugging

Master Laravel Horizon for queue monitoring and Telescope for debugging.

N
Naren Founder & Principal Engineer

20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.

Follow
Production
production tested
July 13, 2026
last updated
2,073
articles · all by Naren
Before you start⏱ 20-25 min read
  • Basic knowledge of Laravel queues and Redis
  • Laravel application with Redis configured
  • Composer installed
  • Access to a server or local environment for running commands
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • 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.
✦ Definition~90s read
What is Laravel Horizon and Telescope?

Laravel Horizon and Telescope are first-party packages for monitoring queues and debugging applications, providing dashboards and insights into job processing, requests, queries, and exceptions.

Imagine you run a busy restaurant kitchen.
Plain-English First

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().

config/horizon.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

return [
    'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'auto',
                'processes' => 3,
                'tries' => 3,
            ],
        ],
        'local' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 1,
                'tries' => 1,
            ],
        ],
    ],
];
⚠ Production Security
📊 Production Insight
In production, set 'balance' => 'auto' to dynamically scale workers based on queue load. Monitor memory usage to avoid OOM kills.
🎯 Key Takeaway
Horizon is configured via 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.

app/Jobs/SendEmailJob.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        // Send email logic
    }

    public function tags()
    {
        return ['send_email', 'user:'.$this->user->id];
    }
}
💡Tagging Jobs
📊 Production Insight
Use Horizon's 'Pause' feature during deployments to allow current jobs to finish before new ones are processed.
🎯 Key Takeaway
Horizon dashboard provides real-time queue monitoring, failed job management, and metrics.

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.

config/telescope.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

return [
    'watchers' => [
        Laravel\Telescope\Watchers\RequestWatcher::class => [
            'enabled' => env('TELESCOPE_ENABLED', true),
            'size_limit' => 100,
        ],
        Laravel\Telescope\Watchers\ExceptionWatcher::class => [
            'enabled' => true,
        ],
        Laravel\Telescope\Watchers\QueryWatcher::class => [
            'enabled' => env('TELESCOPE_ENABLED', true),
            'slow' => 100,
        ],
        // ... other watchers
    ],
    'limit' => 1000,
];
🔥Data Pruning
📊 Production Insight
In production, enable only necessary watchers (e.g., exceptions, slow queries) to reduce overhead. Use 'size_limit' to truncate large request bodies.
🎯 Key Takeaway
Telescope captures detailed debugging information. Configure watchers and data limits for production.

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.

app/Http/Controllers/UserController.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        // N+1 problem example
        $users = User::all();
        foreach ($users as $user) {
            echo $user->profile->bio; // Each access triggers a query
        }
    }
}
Output
Telescope will show multiple similar queries in the Queries tab, indicating an N+1 issue.
⚠ Sensitive Data
📊 Production Insight
Set 'slow' => 100 in QueryWatcher to flag queries taking over 100ms. This helps catch performance regressions early.
🎯 Key Takeaway
Telescope helps identify slow queries, exceptions, and request details. Use it to debug performance and errors.

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.

/etc/supervisor/conf.d/horizon.confPHP
1
2
3
4
5
6
7
8
9
10
[program:horizon]
process_name=%(program_name)s
command=php /path/to/artisan horizon
autostart=true
startsecs=5
startretries=10
user=forge
redirect_stderr=true
stdout_logfile=/var/log/horizon.log
stopwaitsecs=3600
💡Graceful Shutdown
📊 Production Insight
Monitor Horizon's log for memory leaks. Use php artisan horizon:status to check if it's running.
🎯 Key Takeaway
Use Supervisor to keep Horizon running. Telescope runs passively; schedule pruning to manage data.

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.

app/Providers/TelescopeServiceProvider.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

namespace App\Providers;

use Laravel\Telescope\Telescope;
use Illuminate\Support\Facades\Gate;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\TelescopeApplicationServiceProvider;

class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
{
    protected function gate()
    {
        Gate::define('viewTelescope', function ($user) {
            return $user->isAdmin();
        });
    }

    protected function registerTags()
    {
        Telescope::tag(function (IncomingEntry $entry) {
            if ($entry->type === 'request') {
                return ['status:'.$entry->content['response_status']];
            }
            return [];
        });
    }
}
🔥Custom Watchers
📊 Production Insight
Use custom tags to group Telescope entries by customer ID or feature, making it easier to debug issues per tenant.
🎯 Key Takeaway
Extend Horizon and Telescope with custom tags and watchers to monitor application-specific events.
● Production incidentPOST-MORTEMseverity: high

The Silent Queue Failure: How Horizon Saved Our Weekend

Symptom
Users reported not receiving password reset emails for over 4 hours.
Assumption
The developer assumed the queue worker was running fine because no errors appeared in logs.
Root cause
The queue worker process had crashed due to a memory leak, but no monitoring was in place to detect it.
Fix
Implemented Horizon with supervisor configuration to auto-restart workers and set up alerts for queue health.
Key lesson
  • 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.
Production debug guideSymptom to Action4 entries
Symptom · 01
Jobs are queued but never processed
Fix
Check Horizon dashboard for worker status. Ensure supervisor is running. Verify Redis connection.
Symptom · 02
Failed jobs with no clear error
Fix
Use Telescope to view the failed job's exception and stack trace. Check the job's payload and tags.
Symptom · 03
Slow request response times
Fix
In Telescope, examine the request's duration, database queries, and N+1 problems. Look for slow queries.
Symptom · 04
Unexpected exceptions in production
Fix
Telescope captures all exceptions. Filter by type and see the request context, including input and session data.
★ Quick Debug Cheat SheetCommon issues and immediate actions for Horizon and Telescope.
Horizon dashboard shows 'Inactive'
Immediate action
Restart Horizon process
Commands
php artisan horizon:terminate
php artisan horizon
Fix now
Ensure supervisor is configured to auto-restart.
Telescope not recording data+
Immediate action
Check Telescope configuration and environment
Commands
php artisan telescope:clear
php artisan telescope:install
Fix now
Set TELESCOPE_ENABLED=true in .env and run migrations.
Jobs failing with 'Max attempts'+
Immediate action
Inspect failed job details
Commands
php artisan queue:failed
php artisan queue:retry all
Fix now
Fix the underlying issue (e.g., missing model) and retry.
FeatureHorizonTelescope
PurposeQueue monitoring and managementGeneral debugging and profiling
Requires RedisYesNo (but recommended for performance)
Data capturedJob status, metrics, failed jobsRequests, queries, exceptions, mail, etc.
DashboardReal-time queue overviewTimeline of requests and events
CustomizationTags, balance strategiesWatchers, tags, custom records
Production useEssential for queue healthOptional; enable selectively
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
confighorizon.phpreturn [Installing and Configuring Horizon
appJobsSendEmailJob.phpnamespace App\Jobs;Monitoring Queues with Horizon Dashboard
configtelescope.phpreturn [Installing and Configuring Telescope
appHttpControllersUserController.phpnamespace App\Http\Controllers;Debugging with Telescope
etcsupervisorconf.dhorizon.conf[program:horizon]Integrating Horizon and Telescope with Supervisor
appProvidersTelescopeServiceProvider.phpnamespace App\Providers;Advanced Features

Key takeaways

1
Horizon provides real-time queue monitoring and management with Redis.
2
Telescope offers deep debugging for requests, queries, exceptions, and more.
3
Both tools require proper authentication and configuration for production use.
4
Use Supervisor to keep Horizon running reliably in production.
5
Customize tags and watchers to tailor monitoring to your application's needs.

Common mistakes to avoid

4 patterns
×

Not 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 PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does Horizon balance workers across queues?
Q02JUNIOR
What watchers are available in Telescope by default?
Q03SENIOR
How can you customize the data retention policy in Telescope?
Q01 of 03SENIOR

How does Horizon balance workers across queues?

ANSWER
Horizon uses a 'balance' strategy: 'simple' assigns fixed processes, 'auto' dynamically adjusts based on queue load, and 'false' disables balancing.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Do I need Redis to use Horizon?
02
Can I use Telescope in production without performance impact?
03
How do I secure Horizon and Telescope dashboards?
04
What is the difference between Horizon and Telescope?
05
How do I retry failed jobs in Horizon?
N
Naren Founder & Principal Engineer

20+ years shipping production PHP systems at scale. Drawn from code that ran under real load.

Follow
Verified
production tested
July 13, 2026
last updated
2,073
articles · all by Naren
🔥

That's Laravel. Mark it forged?

3 min read · try the examples if you haven't

Previous
Laravel Octane: High-Performance Application Serving
20 / 24 · Laravel
Next
Laravel Filament: Rapid Admin Panel Development