Getting started
Configuration
Every config key Skyline adds on top of the stock config/horizon.php.
Skyline reads the same config/horizon.php as Horizon. Every upstream option — path,
prefix, middleware, waits, silenced, environments
and the rest — behaves exactly as documented in the
Horizon documentation. This page covers only the keys Skyline
adds.
All of them have working defaults. A Horizon config file copied across unchanged is a valid Skyline config file.
Reference
| Key | Env | Default | Purpose |
|---|---|---|---|
log_channel |
HORIZON_LOG_CHANNEL |
null |
Log channel that receives job lifecycle events. null uses the application default channel. |
worker_output |
HORIZON_WORKER_OUTPUT |
'cli' |
'cli' or 'json'. See JSON worker output. |
attempt_exceptions |
— | 1 |
How many previous-attempt failure reasons to retain per job. 0 disables recording. |
trim.delayed |
— | 10080 |
Minutes to retain delayed-job tracking data (7 days). |
metrics.ema_alpha |
— | 0.05 |
Smoothing factor for the runtime and wait-time moving averages. Between 0 and 1. |
metrics.snapshot_lock |
— | 300 |
Seconds a horizon:snapshot lock is held, to de-duplicate concurrent snapshots. Not written to the published file. |
trends.interval |
— | 15 |
Minutes per trend bucket, and the workload sampling cadence. |
trends.retention |
— | 24 |
Hours of trend history to keep and display. |
environments.*.*.queueWeights |
— | [] |
Per-supervisor map of queue name to weight. Only valid when balance is false. |
log_channel
Routes Skyline's job lifecycle log lines to a dedicated channel, so a full end-to-end job trace does not drown your
application log. Leave it null to use the default channel.
'log_channel' => env('HORIZON_LOG_CHANNEL'),
Because each event is emitted at a level appropriate to its severity, the channel's own log level is the volume dial:
point it at a channel with level error to see only failures, or debug for a full trace of
every job. The full event list is on the
Job lifecycle logging page.
worker_output
Each worker writes one line per job to its output. The default 'cli' format is the human-readable table
you see in the terminal; 'json' emits one structured object per line for a log pipeline to ingest.
'worker_output' => env('HORIZON_WORKER_OUTPUT', 'cli'),
JSON output relies on the framework's structured worker output, which exists on Laravel 11 and later. On earlier versions the setting is simply never consulted and output stays in CLI format — no error is raised.
attempt_exceptions
When a job throws or times out but still has retries left, Skyline records why that attempt failed and shows the history under a Previous Attempts panel on the job's dashboard page. Because each entry can carry a full stack trace, the number retained per job is capped.
'attempt_exceptions' => 1,
The default of 1 keeps only the most recent failure reason. Raise it to retain more history — the oldest
entries beyond the limit are dropped — or set it to 0 to turn the feature off entirely.
trim.delayed
Skyline indexes delayed jobs so the Scheduled and Retries views can show them with their real next-run time. That index is trimmed on the same principle as Horizon's other retention settings:
'trim' => [
'recent' => 60,
'pending' => 60,
'completed' => 60,
'recent_failed' => 10080,
'failed' => 10080,
'monitored' => 10080,
'delayed' => 10080,
],
delayed is the Skyline addition; the rest are upstream. The value is in minutes, and the default of
10080 is seven days. Trimming runs periodically from the php artisan horizon master
process, so it requires no separate scheduled command.
metrics
'metrics' => [
'trim_snapshots' => [
'job' => 24,
'queue' => 24,
],
'ema_alpha' => 0.05,
],
ema_alpha is the smoothing factor of the exponential moving average behind Skyline's runtime and
wait-time estimates. It must sit between 0 and 1. Lower values produce a stable average that shrugs off outliers;
higher values react faster to a genuine change in job duration. The default of 0.05 is deliberately
conservative — a single pathological job should not move the estimate much.
trends
Configures the time-series behind the dashboard's workload, wait-time and failure trend charts.
'trends' => [
'interval' => 15,
'retention' => 24,
],
interval is the size of each bucket in minutes, and doubles as the sampling cadence for the workload and
wait series. retention is how many hours of history to keep and display. Together they set the number of
points on the chart: the defaults give 96 buckets across 24 hours. Shortening the interval gives a finer chart at the
cost of more Redis keys and a busier render.
Workload and wait samples are taken from the php artisan horizon master process loop, not from a
scheduled command. Failure counts are recorded as jobs fail. If the master process is not running, no workload
samples are recorded for that period — but nothing else breaks.
queueWeights
A per-supervisor map that turns strict left-to-right queue priority into a proportional policy. It is only valid when
that supervisor runs with 'balance' => false.
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['high', 'default', 'low'],
'balance' => false,
'queueWeights' => [
'high' => 3,
'default' => 2,
// 'low' is omitted, so it keeps the default weight of 1
],
],
See Weighted queues for the semantics, the exception raised
when it is combined with a balancing strategy, and the block_for notes.