From d0a78fb9cee42a392a2f6e4b16aa9a23fe5783db Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Fri, 6 Mar 2026 02:00:38 +0530 Subject: [PATCH 1/3] Add configure-horizon Boost skill --- .../skills/configure-horizon/SKILL.blade.php | 96 +++++++++++++++++++ .../configure-horizon/references/metrics.md | 18 ++++ .../references/notifications.md | 19 ++++ .../references/supervisors.md | 23 +++++ .../configure-horizon/references/tags.md | 18 ++++ 5 files changed, 174 insertions(+) create mode 100644 resources/boost/skills/configure-horizon/SKILL.blade.php create mode 100644 resources/boost/skills/configure-horizon/references/metrics.md create mode 100644 resources/boost/skills/configure-horizon/references/notifications.md create mode 100644 resources/boost/skills/configure-horizon/references/supervisors.md create mode 100644 resources/boost/skills/configure-horizon/references/tags.md diff --git a/resources/boost/skills/configure-horizon/SKILL.blade.php b/resources/boost/skills/configure-horizon/SKILL.blade.php new file mode 100644 index 00000000..be0e0618 --- /dev/null +++ b/resources/boost/skills/configure-horizon/SKILL.blade.php @@ -0,0 +1,96 @@ +--- +name: configuring-horizon +description: "Configures Laravel Horizon for Redis queue management. Triggered when a user mentions Horizon installation, queue supervisor setup, worker configuration, dashboard authorization, auto-scaling, job monitoring, metrics, tags, or notifications. Also applies when troubleshooting blank metrics, LongWaitDetected alerts, or misconfigured worker processes, even when Horizon is not named explicitly — applies to any request about queue workers backed by Redis with a monitoring dashboard, or monitoring Laravel jobs." +license: MIT +metadata: + author: laravel +--- +@php +/** @var \Laravel\Boost\Install\GuidelineAssist $assist */ +@endphp +# Horizon Configuration + +## When to Apply + +Activate this skill when: + +- Installing or configuring Horizon +- Setting up queue supervisors or worker processes +- Restricting access to the Horizon dashboard +- Configuring auto-scaling or balancing strategies +- Setting up job monitoring, tags, metrics, or notifications +- Troubleshooting blank metrics or LongWaitDetected alerts + +## Documentation + +Use `search-docs` for detailed Horizon patterns and documentation (configuration, supervisors, balancing, dashboard auth, tags, notifications, metrics, deployment). + +For deeper guidance on specific topics, read the relevant reference file before implementing: + +- `references/supervisors.md` — supervisor blocks, balancing strategies, multi-queue setups, auto-scaling +- `references/notifications.md` — LongWaitDetected alerts, failed job notifications, `waits` config +- `references/tags.md` — job tagging, dashboard filtering, silencing noisy jobs +- `references/metrics.md` — blank metrics dashboard, snapshot scheduling, retention config + +## Basic Usage + +### Installation + +```bash +{{ $assist->artisanCommand('horizon:install') }} +``` + +### Supervisor Configuration + +Define supervisors in `config/horizon.php`. The `environments` array merges into `defaults` — it does not replace the whole supervisor block: + +@boostsnippet("Supervisor Config", "php") +'defaults' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'auto', + 'minProcesses' => 1, + 'maxProcesses' => 10, + 'tries' => 3, + ], +], + +'environments' => [ + 'production' => [ + 'supervisor-1' => ['maxProcesses' => 10, 'balanceCooldown' => 3], + ], + 'local' => [ + 'supervisor-1' => ['maxProcesses' => 2], + ], +], +@endboostsnippet + +### Dashboard Authorization + +Restrict access in `App\Providers\HorizonServiceProvider`: + +@boostsnippet("Dashboard Gate", "php") +protected function gate(): void +{ + Gate::define('viewHorizon', function (User $user) { + return $user->is_admin; + }); +} +@endboostsnippet + +## Verification + +1. Run `{{ $assist->artisanCommand('horizon') }}` and visit `/horizon` +2. Confirm dashboard access is restricted as expected +3. Check that metrics populate after scheduling `horizon:snapshot` + +## Common Pitfalls + +- Horizon only works with the Redis queue driver — other drivers (database, SQS, etc.) are not supported +- Redis Cluster is not supported — Horizon requires a standalone Redis connection +- Always check `config/horizon.php` to understand the current supervisor and environment configuration before making changes +- `environments` overrides only the keys you specify; it merges into `defaults`, it does not replace +- Timeout chain must be ordered: `retry_after` < job `timeout` < supervisor `timeout`. Wrong order causes jobs to be force-killed and re-queued indefinitely +- Metrics dashboard stays blank until `horizon:snapshot` is scheduled — `php artisan horizon` alone does not populate metrics +- Not using `search-docs` for the latest Horizon documentation diff --git a/resources/boost/skills/configure-horizon/references/metrics.md b/resources/boost/skills/configure-horizon/references/metrics.md new file mode 100644 index 00000000..f4c84d72 --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/metrics.md @@ -0,0 +1,18 @@ +# Metrics & Snapshots + +## Where to Find It + +Search with `search-docs`: +- `"horizon metrics snapshot"` — snapshot command and scheduling +- `"horizon trim snapshots"` — retention configuration + +## What to Watch For + +**The metrics dashboard is blank until `horizon:snapshot` has run at least once.** +Running `php artisan horizon` does not populate metrics automatically. The metrics graph is built from snapshots — you must schedule `php artisan horizon:snapshot` to run every 5 minutes via Laravel's scheduler. If the dashboard is blank, this is almost always the reason. + +**Register the snapshot in the scheduler, not just once manually.** +A single manual run populates the dashboard momentarily but won't keep it updated. Search `"horizon metrics snapshot"` for the exact scheduler registration syntax — it differs slightly between Laravel 10 and 11+. + +**`metrics.trim_snapshots` controls how many data points are retained — not a time duration.** +The `trim_snapshots.job` and `trim_snapshots.queue` values in `config/horizon.php` are counts of snapshots to keep, not minutes or hours. With the default of 24 snapshots at 5-minute intervals, that's 2 hours of history. Increase the value to retain more history; the tradeoff is Redis memory usage. diff --git a/resources/boost/skills/configure-horizon/references/notifications.md b/resources/boost/skills/configure-horizon/references/notifications.md new file mode 100644 index 00000000..ca900fd5 --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/notifications.md @@ -0,0 +1,19 @@ +# Notifications & Alerts + +## Where to Find It + +Search with `search-docs`: +- `"horizon notifications"` — listener registration and event list +- `"horizon long wait detected"` — LongWaitDetected event details +- `"horizon failed job notification"` — JobFailed listener example + +## What to Watch For + +**`waits` in `config/horizon.php` controls the LongWaitDetected threshold — not a notification setting.** +The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This is a config file value, not something set in the notification listener. If alerts are firing too often or too late, adjust `waits`, not the listener code. + +**`LongWaitDetected` is an event — you must register a listener.** +Horizon fires the event but doesn't send any notification by itself. You register a listener for `LongWaitDetected` (and optionally `JobFailed`) inside the `boot()` method of `App\Providers\HorizonServiceProvider`. The listener receives the event and is responsible for dispatching whatever notification (Mail, Slack, etc.) you want. Fetch the docs for the exact listener signature and example. + +**Failed job notifications work differently from queue failures.** +`LongWaitDetected` is about queue depth/wait time. Failed job notifications use the `JobFailed` event, which is also listened to in HorizonServiceProvider. These are two separate listeners with different event classes. Don't conflate them when setting up alerts. diff --git a/resources/boost/skills/configure-horizon/references/supervisors.md b/resources/boost/skills/configure-horizon/references/supervisors.md new file mode 100644 index 00000000..93fc5b3a --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/supervisors.md @@ -0,0 +1,23 @@ +# Supervisor & Balancing Configuration + +## Where to Find It + +Search with `search-docs` before writing any supervisor config — option names and defaults change between Horizon versions: +- `"horizon supervisor configuration"` — full options list +- `"horizon balancing strategies"` — auto, simple, and false modes +- `"horizon autoscaling workers"` — autoScalingStrategy details +- `"horizon environment configuration"` — defaults+environments merge + +## What to Watch For + +**defaults + environments merge semantics.** +The `defaults` array defines the complete base supervisor config. The `environments` array patches it per environment — only the keys you list are overridden. You do not need to repeat every key in each environment block. A common pattern: define `connection`, `queue`, `balance`, `autoScalingStrategy`, `tries`, and `timeout` in `defaults`; only override `maxProcesses`, `balanceMaxShift`, and `balanceCooldown` in `production`. + +**Named supervisors = queue priority.** +Horizon doesn't enforce queue order when using `balance: auto` on a single supervisor — the `queue` array order is ignored for load balancing. If you need true priority (process `notifications` before `default`), use two separately named supervisors: one for the high-priority queue with a higher `maxProcesses`, one for the low-priority queue with a lower cap. Fetch the docs — there's an explicit note about this. + +**`balance: false` for dedicated queues with fixed worker counts.** +Auto-balancing is ideal for variable load, but if you have a queue that should always have exactly N workers (e.g., a video-processing queue limited to 2), set `balance: false` and `maxProcesses: 2`. Auto-balancing would scale it up during bursts, which you may not want. + +**`balanceCooldown` prevents thrashing.** +When using `balance: auto`, the supervisor can scale up and down rapidly under bursty load. Set `balanceCooldown` (seconds between scaling decisions) to something like 3–5 seconds to smooth this out. `balanceMaxShift` limits how many processes are added or removed per cycle. diff --git a/resources/boost/skills/configure-horizon/references/tags.md b/resources/boost/skills/configure-horizon/references/tags.md new file mode 100644 index 00000000..e7c9fb33 --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/tags.md @@ -0,0 +1,18 @@ +# Tags & Silencing + +## Where to Find It + +Search with `search-docs`: +- `"horizon tags"` — tagging API and auto-tagging behaviour +- `"horizon silenced jobs"` — silenced/silenced_tags config options + +## What to Watch For + +**Eloquent models are auto-tagged — you often don't need to add tags manually.** +If a job's constructor accepts Eloquent model instances, Horizon automatically tags the job with `ModelClass:id` (e.g., `App\Models\User:42`). You can filter by this tag in the dashboard without any code changes to the job. Only add a `tags()` method when you need custom tags beyond what auto-tagging provides. + +**`silenced` hides jobs from the completed list — it does not stop them from running.** +Adding a job class to the `silenced` array in `config/horizon.php` removes it from the dashboard's completed jobs view. The job still runs normally. This is purely a dashboard noise-reduction tool, not a way to disable jobs. + +**`silenced_tags` works the same way but matches by tag.** +Any job carrying a matching tag string is hidden from completed jobs. Useful when you want to silence a category of jobs (e.g., all jobs tagged `notifications`) rather than specific classes. From 817cb64b1c00a727833e399dbbc677bf7446d47e Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Fri, 6 Mar 2026 16:06:31 +0530 Subject: [PATCH 2/3] Apply formatting fixes to configure-horizon skill --- .../skills/configure-horizon/SKILL.blade.php | 28 ++++++++--------- .../configure-horizon/references/metrics.md | 19 +++++++----- .../references/notifications.md | 21 +++++++------ .../references/supervisors.md | 30 +++++++++++-------- .../configure-horizon/references/tags.md | 19 +++++++----- 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/resources/boost/skills/configure-horizon/SKILL.blade.php b/resources/boost/skills/configure-horizon/SKILL.blade.php index be0e0618..127ba016 100644 --- a/resources/boost/skills/configure-horizon/SKILL.blade.php +++ b/resources/boost/skills/configure-horizon/SKILL.blade.php @@ -1,6 +1,6 @@ --- name: configuring-horizon -description: "Configures Laravel Horizon for Redis queue management. Triggered when a user mentions Horizon installation, queue supervisor setup, worker configuration, dashboard authorization, auto-scaling, job monitoring, metrics, tags, or notifications. Also applies when troubleshooting blank metrics, LongWaitDetected alerts, or misconfigured worker processes, even when Horizon is not named explicitly — applies to any request about queue workers backed by Redis with a monitoring dashboard, or monitoring Laravel jobs." +description: "Configures Laravel Horizon for Redis queue management. Triggered when a user mentions Horizon installation, queue supervisor setup, worker configuration, dashboard authorization, auto-scaling, job monitoring, metrics, tags, or notifications. Also applies when troubleshooting blank metrics, LongWaitDetected alerts, or misconfigured worker processes, even when Horizon is not named explicitly. Applies to any request about queue workers backed by Redis with a monitoring dashboard, or monitoring Laravel jobs." license: MIT metadata: author: laravel @@ -23,14 +23,14 @@ ## Documentation -Use `search-docs` for detailed Horizon patterns and documentation (configuration, supervisors, balancing, dashboard auth, tags, notifications, metrics, deployment). +Use `search-docs` for detailed Horizon patterns and documentation covering configuration, supervisors, balancing, dashboard authorization, tags, notifications, metrics, and deployment. For deeper guidance on specific topics, read the relevant reference file before implementing: -- `references/supervisors.md` — supervisor blocks, balancing strategies, multi-queue setups, auto-scaling -- `references/notifications.md` — LongWaitDetected alerts, failed job notifications, `waits` config -- `references/tags.md` — job tagging, dashboard filtering, silencing noisy jobs -- `references/metrics.md` — blank metrics dashboard, snapshot scheduling, retention config +- `references/supervisors.md` covers supervisor blocks, balancing strategies, multi-queue setups, and auto-scaling +- `references/notifications.md` covers LongWaitDetected alerts, failed job notifications, and the `waits` config +- `references/tags.md` covers job tagging, dashboard filtering, and silencing noisy jobs +- `references/metrics.md` covers the blank metrics dashboard, snapshot scheduling, and retention config ## Basic Usage @@ -42,7 +42,7 @@ ### Supervisor Configuration -Define supervisors in `config/horizon.php`. The `environments` array merges into `defaults` — it does not replace the whole supervisor block: +Define supervisors in `config/horizon.php`. The `environments` array merges into `defaults` and does not replace the whole supervisor block: @boostsnippet("Supervisor Config", "php") 'defaults' => [ @@ -87,10 +87,10 @@ protected function gate(): void ## Common Pitfalls -- Horizon only works with the Redis queue driver — other drivers (database, SQS, etc.) are not supported -- Redis Cluster is not supported — Horizon requires a standalone Redis connection -- Always check `config/horizon.php` to understand the current supervisor and environment configuration before making changes -- `environments` overrides only the keys you specify; it merges into `defaults`, it does not replace -- Timeout chain must be ordered: `retry_after` < job `timeout` < supervisor `timeout`. Wrong order causes jobs to be force-killed and re-queued indefinitely -- Metrics dashboard stays blank until `horizon:snapshot` is scheduled — `php artisan horizon` alone does not populate metrics -- Not using `search-docs` for the latest Horizon documentation +- Horizon only works with the Redis queue driver. Other drivers such as database and SQS are not supported. +- Redis Cluster is not supported. Horizon requires a standalone Redis connection. +- Always check `config/horizon.php` before making changes to understand the current supervisor and environment configuration. +- The `environments` array overrides only the keys you specify. It merges into `defaults` and does not replace it. +- The timeout chain must be ordered: `retry_after` less than job `timeout` less than supervisor `timeout`. The wrong order causes jobs to be force-killed and re-queued indefinitely. +- The metrics dashboard stays blank until `horizon:snapshot` is scheduled. Running `php artisan horizon` alone does not populate metrics. +- Always use `search-docs` for the latest Horizon documentation rather than relying on this skill alone. diff --git a/resources/boost/skills/configure-horizon/references/metrics.md b/resources/boost/skills/configure-horizon/references/metrics.md index f4c84d72..6ce61013 100644 --- a/resources/boost/skills/configure-horizon/references/metrics.md +++ b/resources/boost/skills/configure-horizon/references/metrics.md @@ -3,16 +3,19 @@ ## Where to Find It Search with `search-docs`: -- `"horizon metrics snapshot"` — snapshot command and scheduling -- `"horizon trim snapshots"` — retention configuration +- `"horizon metrics snapshot"` for the snapshot command and scheduling +- `"horizon trim snapshots"` for retention configuration ## What to Watch For -**The metrics dashboard is blank until `horizon:snapshot` has run at least once.** -Running `php artisan horizon` does not populate metrics automatically. The metrics graph is built from snapshots — you must schedule `php artisan horizon:snapshot` to run every 5 minutes via Laravel's scheduler. If the dashboard is blank, this is almost always the reason. +### Metrics dashboard stays blank until `horizon:snapshot` is scheduled -**Register the snapshot in the scheduler, not just once manually.** -A single manual run populates the dashboard momentarily but won't keep it updated. Search `"horizon metrics snapshot"` for the exact scheduler registration syntax — it differs slightly between Laravel 10 and 11+. +Running `php artisan horizon` does not populate metrics automatically. The metrics graph is built from snapshots, so `php artisan horizon:snapshot` must be scheduled to run every 5 minutes via Laravel's scheduler. -**`metrics.trim_snapshots` controls how many data points are retained — not a time duration.** -The `trim_snapshots.job` and `trim_snapshots.queue` values in `config/horizon.php` are counts of snapshots to keep, not minutes or hours. With the default of 24 snapshots at 5-minute intervals, that's 2 hours of history. Increase the value to retain more history; the tradeoff is Redis memory usage. +### Register the snapshot in the scheduler rather than running it manually + +A single manual run populates the dashboard momentarily but will not keep it updated. Search `"horizon metrics snapshot"` for the exact scheduler registration syntax, which differs between Laravel 10 and 11+. + +### `metrics.trim_snapshots` is a snapshot count, not a time duration + +The `trim_snapshots.job` and `trim_snapshots.queue` values in `config/horizon.php` are counts of snapshots to keep, not minutes or hours. With the default of 24 snapshots at 5-minute intervals, that provides 2 hours of history. Increase the value to retain more history at the cost of Redis memory usage. diff --git a/resources/boost/skills/configure-horizon/references/notifications.md b/resources/boost/skills/configure-horizon/references/notifications.md index ca900fd5..2dc1725e 100644 --- a/resources/boost/skills/configure-horizon/references/notifications.md +++ b/resources/boost/skills/configure-horizon/references/notifications.md @@ -3,17 +3,20 @@ ## Where to Find It Search with `search-docs`: -- `"horizon notifications"` — listener registration and event list -- `"horizon long wait detected"` — LongWaitDetected event details -- `"horizon failed job notification"` — JobFailed listener example +- `"horizon notifications"` for listener registration and the event list +- `"horizon long wait detected"` for LongWaitDetected event details +- `"horizon failed job notification"` for a JobFailed listener example ## What to Watch For -**`waits` in `config/horizon.php` controls the LongWaitDetected threshold — not a notification setting.** -The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This is a config file value, not something set in the notification listener. If alerts are firing too often or too late, adjust `waits`, not the listener code. +### `waits` in `config/horizon.php` controls the LongWaitDetected threshold, not the notification itself -**`LongWaitDetected` is an event — you must register a listener.** -Horizon fires the event but doesn't send any notification by itself. You register a listener for `LongWaitDetected` (and optionally `JobFailed`) inside the `boot()` method of `App\Providers\HorizonServiceProvider`. The listener receives the event and is responsible for dispatching whatever notification (Mail, Slack, etc.) you want. Fetch the docs for the exact listener signature and example. +The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This value is set in the config file, not in the notification listener. If alerts are firing too often or too late, adjust `waits` rather than the listener code. -**Failed job notifications work differently from queue failures.** -`LongWaitDetected` is about queue depth/wait time. Failed job notifications use the `JobFailed` event, which is also listened to in HorizonServiceProvider. These are two separate listeners with different event classes. Don't conflate them when setting up alerts. +### `LongWaitDetected` fires an event that requires a registered listener to send notifications + +Horizon fires the event but does not send any notification by itself. Register a listener for `LongWaitDetected` (and optionally `JobFailed`) inside the `boot()` method of `App\Providers\HorizonServiceProvider`. The listener receives the event and is responsible for dispatching the appropriate notification such as Mail or Slack. Fetch the docs for the exact listener signature and example. + +### Failed job notifications use a separate event from LongWaitDetected + +`LongWaitDetected` covers queue depth and wait time. Failed job notifications use the `JobFailed` event, which is also registered in HorizonServiceProvider. These are two separate listeners with different event classes. diff --git a/resources/boost/skills/configure-horizon/references/supervisors.md b/resources/boost/skills/configure-horizon/references/supervisors.md index 93fc5b3a..b71285cf 100644 --- a/resources/boost/skills/configure-horizon/references/supervisors.md +++ b/resources/boost/skills/configure-horizon/references/supervisors.md @@ -2,22 +2,26 @@ ## Where to Find It -Search with `search-docs` before writing any supervisor config — option names and defaults change between Horizon versions: -- `"horizon supervisor configuration"` — full options list -- `"horizon balancing strategies"` — auto, simple, and false modes -- `"horizon autoscaling workers"` — autoScalingStrategy details -- `"horizon environment configuration"` — defaults+environments merge +Search with `search-docs` before writing any supervisor config, as option names and defaults change between Horizon versions: +- `"horizon supervisor configuration"` for the full options list +- `"horizon balancing strategies"` for auto, simple, and false modes +- `"horizon autoscaling workers"` for autoScalingStrategy details +- `"horizon environment configuration"` for the defaults and environments merge ## What to Watch For -**defaults + environments merge semantics.** -The `defaults` array defines the complete base supervisor config. The `environments` array patches it per environment — only the keys you list are overridden. You do not need to repeat every key in each environment block. A common pattern: define `connection`, `queue`, `balance`, `autoScalingStrategy`, `tries`, and `timeout` in `defaults`; only override `maxProcesses`, `balanceMaxShift`, and `balanceCooldown` in `production`. +### The `environments` array merges into `defaults` rather than replacing it -**Named supervisors = queue priority.** -Horizon doesn't enforce queue order when using `balance: auto` on a single supervisor — the `queue` array order is ignored for load balancing. If you need true priority (process `notifications` before `default`), use two separately named supervisors: one for the high-priority queue with a higher `maxProcesses`, one for the low-priority queue with a lower cap. Fetch the docs — there's an explicit note about this. +The `defaults` array defines the complete base supervisor config. The `environments` array patches it per environment, overriding only the keys listed. There is no need to repeat every key in each environment block. A common pattern is to define `connection`, `queue`, `balance`, `autoScalingStrategy`, `tries`, and `timeout` in `defaults`, then override only `maxProcesses`, `balanceMaxShift`, and `balanceCooldown` in `production`. -**`balance: false` for dedicated queues with fixed worker counts.** -Auto-balancing is ideal for variable load, but if you have a queue that should always have exactly N workers (e.g., a video-processing queue limited to 2), set `balance: false` and `maxProcesses: 2`. Auto-balancing would scale it up during bursts, which you may not want. +### Use separate named supervisors to enforce queue priority -**`balanceCooldown` prevents thrashing.** -When using `balance: auto`, the supervisor can scale up and down rapidly under bursty load. Set `balanceCooldown` (seconds between scaling decisions) to something like 3–5 seconds to smooth this out. `balanceMaxShift` limits how many processes are added or removed per cycle. +Horizon does not enforce queue order when using `balance: auto` on a single supervisor. The `queue` array order is ignored for load balancing. To process `notifications` before `default`, use two separately named supervisors: one for the high-priority queue with a higher `maxProcesses`, and one for the low-priority queue with a lower cap. The docs include an explicit note about this. + +### Use `balance: false` to keep a fixed number of workers on a dedicated queue + +Auto-balancing suits variable load, but if a queue should always have exactly N workers such as a video-processing queue limited to 2, set `balance: false` and `maxProcesses: 2`. Auto-balancing would scale it up during bursts, which may be undesirable. + +### Set `balanceCooldown` to prevent rapid worker scaling under bursty load + +When using `balance: auto`, the supervisor can scale up and down rapidly under bursty load. Set `balanceCooldown` to the number of seconds between scaling decisions, typically 3 to 5, to smooth this out. `balanceMaxShift` limits how many processes are added or removed per cycle. diff --git a/resources/boost/skills/configure-horizon/references/tags.md b/resources/boost/skills/configure-horizon/references/tags.md index e7c9fb33..8234e4ad 100644 --- a/resources/boost/skills/configure-horizon/references/tags.md +++ b/resources/boost/skills/configure-horizon/references/tags.md @@ -3,16 +3,19 @@ ## Where to Find It Search with `search-docs`: -- `"horizon tags"` — tagging API and auto-tagging behaviour -- `"horizon silenced jobs"` — silenced/silenced_tags config options +- `"horizon tags"` for the tagging API and auto-tagging behaviour +- `"horizon silenced jobs"` for the `silenced` and `silenced_tags` config options ## What to Watch For -**Eloquent models are auto-tagged — you often don't need to add tags manually.** -If a job's constructor accepts Eloquent model instances, Horizon automatically tags the job with `ModelClass:id` (e.g., `App\Models\User:42`). You can filter by this tag in the dashboard without any code changes to the job. Only add a `tags()` method when you need custom tags beyond what auto-tagging provides. +### Eloquent model jobs are tagged automatically without any extra code -**`silenced` hides jobs from the completed list — it does not stop them from running.** -Adding a job class to the `silenced` array in `config/horizon.php` removes it from the dashboard's completed jobs view. The job still runs normally. This is purely a dashboard noise-reduction tool, not a way to disable jobs. +If a job's constructor accepts Eloquent model instances, Horizon automatically tags the job with `ModelClass:id` such as `App\Models\User:42`. These tags are filterable in the dashboard without any changes to the job class. Only add a `tags()` method when custom tags beyond auto-tagging are needed. -**`silenced_tags` works the same way but matches by tag.** -Any job carrying a matching tag string is hidden from completed jobs. Useful when you want to silence a category of jobs (e.g., all jobs tagged `notifications`) rather than specific classes. +### `silenced` hides jobs from the dashboard completed list but does not stop them from running + +Adding a job class to the `silenced` array in `config/horizon.php` removes it from the completed jobs view. The job still runs normally. This is a dashboard noise-reduction tool, not a way to disable jobs. + +### `silenced_tags` hides all jobs carrying a matching tag from the completed list + +Any job carrying a matching tag string is hidden from the completed jobs view. This is useful for silencing a category of jobs such as all jobs tagged `notifications`, rather than silencing specific classes. From c931b116b602facc6cbd12577665b968d2e0e7c1 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Fri, 6 Mar 2026 17:29:06 +0530 Subject: [PATCH 3/3] Tighten configure-horizon skill activation to require explicit Horizon mention --- .../skills/configure-horizon/SKILL.blade.php | 18 ++++++++++-------- .../references/notifications.md | 15 +++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/resources/boost/skills/configure-horizon/SKILL.blade.php b/resources/boost/skills/configure-horizon/SKILL.blade.php index 127ba016..d98dcb7f 100644 --- a/resources/boost/skills/configure-horizon/SKILL.blade.php +++ b/resources/boost/skills/configure-horizon/SKILL.blade.php @@ -1,6 +1,6 @@ --- name: configuring-horizon -description: "Configures Laravel Horizon for Redis queue management. Triggered when a user mentions Horizon installation, queue supervisor setup, worker configuration, dashboard authorization, auto-scaling, job monitoring, metrics, tags, or notifications. Also applies when troubleshooting blank metrics, LongWaitDetected alerts, or misconfigured worker processes, even when Horizon is not named explicitly. Applies to any request about queue workers backed by Redis with a monitoring dashboard, or monitoring Laravel jobs." +description: "Configures Laravel Horizon for Redis queue management. Activate when the user explicitly mentions Horizon by name. Covers Horizon installation, supervisor configuration, worker processes, dashboard authorization, auto-scaling, balancing strategies, job monitoring, metrics, tags, and notifications. Also applies when troubleshooting Horizon-specific issues such as blank metrics, LongWaitDetected alerts, or misconfigured Horizon workers. Do NOT activate for generic queue, Redis, or job monitoring questions that do not mention Horizon." license: MIT metadata: author: laravel @@ -12,14 +12,16 @@ ## When to Apply -Activate this skill when: +Activate this skill when the user explicitly mentions **Horizon** by name. Examples: - Installing or configuring Horizon -- Setting up queue supervisors or worker processes +- Setting up Horizon supervisors or worker processes - Restricting access to the Horizon dashboard -- Configuring auto-scaling or balancing strategies -- Setting up job monitoring, tags, metrics, or notifications -- Troubleshooting blank metrics or LongWaitDetected alerts +- Configuring Horizon auto-scaling or balancing strategies +- Setting up Horizon job monitoring, tags, metrics, or notifications +- Troubleshooting Horizon blank metrics or LongWaitDetected alerts + +Do NOT activate for generic queue workers, Redis configuration, or job monitoring questions that do not mention Horizon. ## Documentation @@ -28,7 +30,7 @@ For deeper guidance on specific topics, read the relevant reference file before implementing: - `references/supervisors.md` covers supervisor blocks, balancing strategies, multi-queue setups, and auto-scaling -- `references/notifications.md` covers LongWaitDetected alerts, failed job notifications, and the `waits` config +- `references/notifications.md` covers LongWaitDetected alerts, notification routing, and the `waits` config - `references/tags.md` covers job tagging, dashboard filtering, and silencing noisy jobs - `references/metrics.md` covers the blank metrics dashboard, snapshot scheduling, and retention config @@ -91,6 +93,6 @@ protected function gate(): void - Redis Cluster is not supported. Horizon requires a standalone Redis connection. - Always check `config/horizon.php` before making changes to understand the current supervisor and environment configuration. - The `environments` array overrides only the keys you specify. It merges into `defaults` and does not replace it. -- The timeout chain must be ordered: `retry_after` less than job `timeout` less than supervisor `timeout`. The wrong order causes jobs to be force-killed and re-queued indefinitely. +- The timeout chain must be ordered: job `timeout` less than supervisor `timeout` less than `retry_after`. The wrong order can cause jobs to be retried before Horizon finishes timing them out. - The metrics dashboard stays blank until `horizon:snapshot` is scheduled. Running `php artisan horizon` alone does not populate metrics. - Always use `search-docs` for the latest Horizon documentation rather than relying on this skill alone. diff --git a/resources/boost/skills/configure-horizon/references/notifications.md b/resources/boost/skills/configure-horizon/references/notifications.md index 2dc1725e..d6d3feed 100644 --- a/resources/boost/skills/configure-horizon/references/notifications.md +++ b/resources/boost/skills/configure-horizon/references/notifications.md @@ -3,20 +3,19 @@ ## Where to Find It Search with `search-docs`: -- `"horizon notifications"` for listener registration and the event list +- `"horizon notifications"` for Horizon's built-in notification routing helpers - `"horizon long wait detected"` for LongWaitDetected event details -- `"horizon failed job notification"` for a JobFailed listener example ## What to Watch For -### `waits` in `config/horizon.php` controls the LongWaitDetected threshold, not the notification itself +### `waits` in `config/horizon.php` controls the LongWaitDetected threshold -The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This value is set in the config file, not in the notification listener. If alerts are firing too often or too late, adjust `waits` rather than the listener code. +The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This value is set in the config file, not in Horizon's notification routing. If alerts are firing too often or too late, adjust `waits` rather than the routing configuration. -### `LongWaitDetected` fires an event that requires a registered listener to send notifications +### Use Horizon's built-in notification routing in `HorizonServiceProvider` -Horizon fires the event but does not send any notification by itself. Register a listener for `LongWaitDetected` (and optionally `JobFailed`) inside the `boot()` method of `App\Providers\HorizonServiceProvider`. The listener receives the event and is responsible for dispatching the appropriate notification such as Mail or Slack. Fetch the docs for the exact listener signature and example. +Configure notifications in the `boot()` method of `App\Providers\HorizonServiceProvider` using `Horizon::routeMailNotificationsTo()`, `Horizon::routeSlackNotificationsTo()`, or `Horizon::routeSmsNotificationsTo()`. Horizon already wires `LongWaitDetected` to its notification sender, so the documented setup is notification routing rather than manual listener registration. -### Failed job notifications use a separate event from LongWaitDetected +### Failed job alerts are separate from Horizon's documented notification routing -`LongWaitDetected` covers queue depth and wait time. Failed job notifications use the `JobFailed` event, which is also registered in HorizonServiceProvider. These are two separate listeners with different event classes. +Horizon's 12.x documentation covers built-in long-wait notifications. Do not assume the docs provide a `JobFailed` listener example in `HorizonServiceProvider`. If a user needs failed job alerts, treat that as custom queue event handling and consult the queue documentation instead of Horizon's notification-routing API.