Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Horizon Laravel Package

laravel/horizon

Laravel Horizon adds a polished dashboard and code-driven configuration for Laravel Redis queues. Monitor job throughput, runtime, failures, and worker status, with all queue worker settings kept in a single config file for easy version control.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/horizon
    

    Publish Horizon's configuration and migrations:

    php artisan horizon:install
    

    Run migrations:

    php artisan migrate
    
  2. Configure Redis: Ensure your config/horizon.php points to a Redis connection. Example:

    'connections' => [
        'redis' => [
            'driver' => 'redis',
            'connection' => 'redis',
            'queue' => 'default',
            'retry_after' => 90,
        ],
    ],
    
  3. Start Horizon:

    php artisan horizon
    

    Access the dashboard at http://your-app.test/horizon.

First Use Case

Dispatch a job and monitor it:

// Dispatch a job
SendEmail::dispatch('user@example.com', 'Welcome!');

// Monitor via Horizon dashboard
// - View job status (processing, failed, etc.)
// - Check runtime, payload, and exceptions

Implementation Patterns

Core Workflows

  1. Worker Configuration: Define workers in config/horizon.php:

    'workers' => [
        'default' => [
            'supervisor' => 'default',
            'queue' => ['default'],
            'balance' => 'auto',
            'processes' => 1,
            'tries' => 1,
        ],
    ],
    
    • Use balance: 'auto' for dynamic scaling.
    • Set processes based on CPU cores (e.g., processes: 4).
  2. Job Tagging & Prioritization: Tag jobs for filtering in Horizon:

    SendEmail::dispatch('user@example.com')->onQueue('emails')->tag(['newsletter', 'high-priority']);
    

    Configure tags in config/horizon.php:

    'tags' => [
        'newsletter' => ['color' => 'blue', 'description' => 'Newsletter emails'],
    ],
    
  3. Batch Processing: Group jobs into batches for unified monitoring:

    $batch = Bus::batch([
        new SendEmail('user1@example.com'),
        new SendEmail('user2@example.com'),
    ])->then(function (Batch $batch) {
        // Handle batch completion
    })->dispatch();
    

    View batches in Horizon under the "Batches" tab.

  4. Supervisor Management: Use php artisan horizon:terminate to gracefully shut down workers. Restart supervisors via:

    php artisan horizon:terminate && php artisan horizon
    

Integration Tips

  • Event Listeners: Listen to Horizon events (e.g., JobProcessed, JobFailed) for custom logic:

    public function handle(JobProcessed $event) {
        Log::info("Job {$event->job->id} processed in {$event->duration}ms");
    }
    
  • Custom Metrics: Extend Horizon’s monitoring with custom metrics via the Monitor facade:

    use Illuminate\Support\Facades\Horizon;
    
    Horizon::monitor('custom_metric', function () {
        return Cache::get('custom_metric_value');
    });
    
  • Environment-Specific Configs: Use environment variables in config/horizon.php:

    'processes' => env('QUEUE_WORKERS', 4),
    

Gotchas and Tips

Pitfalls

  1. Redis Connection Issues:

    • Ensure Redis is running and accessible. Horizon fails fast if Redis is down (v5.45.0+).
    • Avoid naming your Redis connection horizon (reserved).
  2. Memory Leaks:

    • Use horizon:listen (v5.43.0+) instead of horizon:work for long-running processes to prevent memory buildup.
    • Monitor worker memory via the dashboard’s "Supervisors" tab.
  3. Job Stuck in "Pending":

    • Race conditions (fixed in v5.42.0) can cause this. Restart Horizon if jobs are stuck.
  4. Dashboard Not Loading:

    • Clear Horizon’s cache:
      php artisan horizon:clear-cache
      
    • Check browser console for JavaScript errors (e.g., localStorage collisions in v5.45.1).

Debugging

  • Log Levels: Increase Horizon’s log level in config/horizon.php:

    'logging' => [
        'driver' => 'single',
        'level' => 'debug',
    ],
    
  • Job Payloads: Inspect failed jobs’ payloads in the "Failed Jobs" tab. Use horizon:flush to clear old jobs:

    php artisan horizon:flush --queue=failed
    
  • Worker Processes: Check process counts with:

    php artisan horizon:status
    

    Kill orphaned processes manually if needed.

Tips

  1. Delayed Jobs: Use delay() on jobs to schedule execution:

    SendEmail::dispatch()->delay(now()->addMinutes(10));
    

    Monitor delayed jobs in Horizon’s "Delayed" tab.

  2. Silenced Tags: Hide specific tags from the dashboard:

    'silenced_tags' => ['logs', 'internal'],
    
  3. Custom Views: Override Horizon’s Blade views in resources/views/vendor/horizon/.

  4. Local Development: Use horizon:listen --local to bypass private tunnel restrictions (v5.45.0+).

  5. Batch Searching: Search across all jobs/batches using the global search bar (v5.45.0+).

  6. PHP 8.5+ Compatibility: Use horizon:listen for PHP 8.5+ to avoid setAccessible() deprecation warnings (v5.40.1+).

  7. Worker Cooldown: Configure cooldowns for failed processes:

    'cooldown' => [
        'default' => 60, // seconds
    ],
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport