Laravel Horizon

업데이트됨

번역일: 2026년 7월 31일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 7월 31일
번역 갱신
2026년 7월 31일

Laravel Horizon

소개

NOTE

Laravel Horizon을 사용하려면 큐 드라이버로 반드시 Redis를 사용해야 합니다. 다른 드라이버(database, SQS 등)와는 함께 사용할 수 없습니다.

Laravel Horizon은 Redis 기반 큐를 위한 대시보드와 코드 기반 설정 도구를 제공합니다. 직관적인 UI를 통해 Job 처리량, 실행 시간, 실패한 Job 등 큐의 주요 지표를 한눈에 파악할 수 있습니다.

Horizon을 사용하면 워커 프로세스 설정을 별도의 서버 설정 파일이 아닌 Laravel 애플리케이션 코드 안에서 관리합니다. 이 방식의 장점은 팀 전체가 설정을 공유하고 버전 관리(Git 등)로 추적할 수 있다는 점입니다.

설치

WARNING

Laravel Horizon은 큐 연결에 Redis를 사용해야 합니다. config/queue.php에서 큐 연결이 redis 드라이버를 사용하도록 설정되어 있는지 먼저 확인하세요.

Composer를 사용해 Horizon을 설치합니다:

composer require laravel/horizon

설치 후 horizon:install Artisan 명령어로 설정 파일과 에셋을 게시합니다:

php artisan horizon:install

설정

에셋을 게시하면 config/horizon.php 파일이 생성됩니다. 이 파일에서 워커 설정을 정의합니다. 각 옵션에는 설명이 포함되어 있으니 꼼꼼히 읽어보세요.

WARNING

Horizon은 내부적으로 horizon이라는 Redis 연결 이름을 사용합니다. 이 이름은 예약어이므로 database.php의 Redis 연결이나 horizon.phpuse 옵션에 다른 목적으로 horizon을 할당하지 마세요.

환경별 설정

설치 후 가장 먼저 이해해야 할 설정이 environments 옵션입니다. 이 옵션은 애플리케이션이 실행되는 각 환경(로컬, 프로덕션 등)별로 워커 프로세스 옵션을 정의하는 배열입니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, ], ], 'local' => [ 'supervisor-1' => [ 'maxProcesses' => 3, ], ], ],

Horizon을 시작하면 현재 실행 환경에 맞는 워커 프로세스 설정을 사용합니다. 각 환경에는 하나 이상의 supervisor를 정의할 수 있으며, supervisor는 워커 프로세스 그룹을 관리합니다.

NOTE

config/horizon.phpenvironments 배열에 현재 실행 환경이 정의되어 있지 않으면, APP_ENV 환경 변수와 일치하는 항목이 없어 Horizon이 정상적으로 동작하지 않습니다.

Supervisor

기본 설정 파일에서 볼 수 있듯이, 각 환경에는 하나 이상의 "supervisor"를 정의할 수 있습니다. 기본 supervisor 이름은 supervisor-1이지만, 원하는 이름으로 변경해도 됩니다. 각 supervisor는 본질적으로 워커 프로세스 그룹을 감독하는 역할을 합니다. 즉, 프로세스의 수를 유지하고 지정된 큐에서 Job을 처리하도록 워커를 분배합니다.

특정 환경에서 새로운 워커 그룹을 정의하려면 supervisor를 추가로 등록하면 됩니다. 예를 들어, 특정 큐에 대해 다른 밸런싱 전략이나 워커 수를 지정하고 싶을 때 활용할 수 있습니다:

'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'autoScalingStrategy' => 'time', 'minProcesses' => 1, 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, 'tries' => 3, ], 'supervisor-2' => [ 'connection' => 'redis', 'queue' => ['high-priority'], 'balance' => 'auto', 'autoScalingStrategy' => 'time', 'minProcesses' => 1, 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, 'tries' => 3, ], ],

점검 모드(Maintenance Mode)

애플리케이션이 점검 모드일 때는 supervisor의 force 옵션을 true로 설정하지 않는 한, Horizon이 큐에 있는 Job을 처리하지 않습니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'force' => true, ], ], ],

기본값 설정

Horizon의 기본 설정 파일에는 defaults 옵션이 있습니다. 이 옵션은 각 supervisor의 기본값을 지정합니다. supervisor의 기본값은 각 환경별 supervisor 설정에 병합되므로, 중복된 설정을 반복해서 작성할 필요가 없습니다:

'defaults' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'autoScalingStrategy' => 'time', 'maxProcesses' => 1, 'maxTime' => 0, 'maxJobs' => 0, 'memory' => 128, 'tries' => 1, 'timeout' => 60, 'nice' => 0, ], ],

대시보드 접근 제한

Horizon 대시보드는 /horizon 경로에서 접근할 수 있습니다. 기본적으로 local 환경에서만 접근이 허용됩니다. local 환경이 아닌 프로덕션 등 다른 환경에서 접근을 허용하려면 app/Providers/HorizonServiceProvider.php에 정의된 gate 메서드를 수정해야 합니다.

gate 메서드에서는 누가 Horizon에 접근할 수 있는지를 제어합니다. 인증된 사용자의 이메일 주소나 역할(role) 등을 기준으로 접근을 허용하거나 차단할 수 있습니다:

/** * Horizon 게이트 등록 * * 이 게이트는 로컬이 아닌 환경에서 * Horizon 접근 가능 여부를 결정합니다. */ protected function gate(): void { Gate::define('viewHorizon', function (User $user) { return in_array($user->email, [ 'admin@example.com', ]); }); }

대체 인증 전략

Laravel은 게이트 클로저에 인증된 사용자를 자동으로 주입합니다. 만약 IP 주소 제한처럼 다른 방식으로 Horizon 보안을 적용하고 있다면, Horizon 사용자는 "로그인"이 필요하지 않을 수도 있습니다. 이 경우 위의 클로저 시그니처를 function (User $user)에서 function (?User $user)로 변경하여 인증되지 않은 사용자도 허용할 수 있습니다.

최대 Job 시도 횟수

Horizon은 Job의 최대 시도 횟수를 지정하는 두 가지 방법을 제공합니다. 애플리케이션의 config/horizon.php에서 설정하거나, Job 클래스에서 직접 정의할 수 있습니다.

config/horizon.php에서 tries 값을 설정하면 해당 supervisor에서 처리되는 모든 Job에 적용됩니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'tries' => 3, // 최대 3번 시도 // ... ], ], ],

Job 클래스에 $tries 프로퍼티를 정의하면 해당 Job에만 적용됩니다:

<?php namespace App\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class ProcessOrder implements ShouldQueue { use Queueable; /** * 최대 시도 횟수 */ public int $tries = 5; }

Job 타임아웃

마찬가지로, Job의 최대 실행 시간(타임아웃)도 config/horizon.php에서 설정하거나 Job 클래스에서 직접 정의할 수 있습니다:

config/horizon.phptimeout 값을 설정하면 해당 supervisor에서 처리되는 모든 Job에 적용됩니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'timeout' => 300, // 5분 // ... ], ], ],

Job 클래스에 $timeout 프로퍼티를 정의하면 해당 Job에만 적용됩니다:

<?php namespace App\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class ProcessOrder implements ShouldQueue { use Queueable; /** * 타임아웃(초 단위) */ public int $timeout = 120; }

WARNING

PHP의 pcntl 확장 모듈이 설치되어 있어야 Job 타임아웃이 올바르게 동작합니다. 또한 Job의 타임아웃 값은 항상 retry_after 값보다 작아야 합니다. 그렇지 않으면 Job이 실제로 완료되기 전에 재시도가 발생할 수 있습니다. 자세한 내용은 큐 설정 문서를 참고하세요.

Job Backoff

Job이 실패했을 때 얼마나 대기한 후 재시도할지를 설정합니다. Job 클래스에 $backoff 프로퍼티를 정의하면 됩니다:

<?php namespace App\Jobs; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class ProcessOrder implements ShouldQueue { use Queueable; /** * 재시도 전 대기 시간(초 단위) */ public int $backoff = 10; }

재시도마다 대기 시간을 다르게 설정하고 싶다면 배열로 지정할 수 있습니다. 예를 들어 첫 번째 재시도는 10초 후, 두 번째는 15초 후, 세 번째 이후부터는 20초 후에 재시도합니다:

public array $backoff = [10, 15, 20];

기타 워커 옵션

config/horizon.php에서 제공하는 추가 워커 옵션은 다음과 같습니다. 각 옵션에 대한 자세한 설명은 큐 문서를 참고하세요:

옵션설명
balance밸런싱 전략 (auto, simple, false)
connection사용할 Redis 연결 이름
maxProcesses최대 워커 프로세스 수
minProcesses최소 워커 프로세스 수
maxTime워커 실행 최대 시간(초)
maxJobs워커가 처리할 최대 Job 수
memory워커당 최대 메모리(MB)
nice프로세스 우선순위
queue처리할 큐 목록
sleep큐가 비었을 때 대기 시간(초)
timeoutJob 타임아웃(초)
triesJob 최대 시도 횟수

숨긴 Job

애플리케이션이나 서드파티 패키지에서 발송되는 일부 Job이 대시보드에 표시되지 않기를 원할 수 있습니다. 이런 Job들을 "숨김" 처리하면 대시보드의 "완료된 Job" 목록에서 제외됩니다. 특정 Job을 숨기려면 config/horizon.phpsilenced 옵션에 해당 Job의 클래스 이름을 추가하면 됩니다:

'silenced' => [ App\Jobs\SendNotification::class, ],

또는 숨기고 싶은 Job 클래스에서 Laravel\Horizon\Contracts\Silenced 인터페이스를 구현할 수도 있습니다. 이 인터페이스를 구현한 Job은 silenced 배열에 없어도 자동으로 숨겨집니다:

use Laravel\Horizon\Contracts\Silenced; class SendNotification implements ShouldQueue, Silenced { use Queueable; // ... }

밸런싱 전략

Horizon은 워커 프로세스를 큐에 어떻게 분배할지 결정하는 세 가지 밸런싱 전략을 제공합니다: auto, simple, 그리고 false(밸런싱 없음). 각 전략의 특성을 이해하고 서비스 규모와 요구사항에 맞는 전략을 선택하세요.

자동 밸런싱 (auto)

auto 전략은 큐의 현재 부하에 따라 워커 프로세스 수를 자동으로 조절합니다. 예를 들어, notifications 큐에 대기 중인 Job이 많고 render 큐가 비어있다면, Horizon은 notifications 큐에 더 많은 워커를 배정합니다.

autoScalingStrategy 옵션으로 자동 스케일링 방식을 선택할 수 있습니다:

  • time: 큐를 비우는 데 걸리는 총 시간을 기준으로 프로세스를 배분합니다. 처리 시간이 긴 Job이 많은 큐에 더 많은 워커를 배정합니다.
  • size: 큐에 쌓인 Job 수를 기준으로 프로세스를 배분합니다. 단순하고 직관적인 방식입니다.

balanceMaxShiftbalanceCooldown 옵션으로 스케일링 속도를 제어할 수 있습니다:

  • balanceMaxShift: 한 번의 스케일링 주기에 변경할 수 있는 최대 프로세스 수
  • balanceCooldown: 스케일링 이후 다음 스케일링까지 대기할 시간(초)
'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default'], 'balance' => 'auto', 'autoScalingStrategy' => 'time', 'minProcesses' => 1, 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, 'tries' => 3, ], ], ],

단순 밸런싱 (simple)

simple 전략은 들어오는 Job을 큐에 균등하게 분배합니다:

'balance' => 'simple',

밸런싱 없음 (false)

balance 옵션을 false로 설정하면 Horizon은 설정 파일에 나열된 순서대로 큐를 처리합니다. 라라벨의 기본 queue:work 명령어와 동일한 동작 방식입니다:

'balance' => false,

NOTE

false 밸런싱 전략을 사용할 때는 minProcessesmaxProcesses 설정이 무시됩니다. 프로세스 수는 고정됩니다.

Horizon 업그레이드

Horizon의 새 주요 버전으로 업그레이드할 때는 반드시 업그레이드 가이드를 꼼꼼히 읽어보세요.

또한, Horizon의 어떤 버전으로 업그레이드하든 에셋을 다시 게시해야 합니다:

php artisan horizon:publish

에셋을 최신 상태로 유지하고 향후 업데이트 시 문제를 예방하려면, composer.jsonpost-update-cmd 스크립트에 vendor:publish --tag=laravel-assets 명령어를 추가해 두는 것이 좋습니다:

{ "scripts": { "post-update-cmd": [ "@php artisan vendor:publish --tag=laravel-assets --ansi --force" ] } }

Horizon 실행

config/horizon.php에서 supervisor와 워커 설정을 마쳤다면 horizon Artisan 명령어로 Horizon을 시작할 수 있습니다. 이 명령어 하나로 현재 환경에 맞는 모든 워커 프로세스가 함께 시작됩니다:

php artisan horizon

Horizon 프로세스를 일시 중지하거나 재개하려면 horizon:pausehorizon:continue 명령어를 사용합니다:

php artisan horizon:pausephp artisan horizon:continue

특정 Horizon supervisor만 일시 중지하거나 재개하려면 horizon:pause-supervisorhorizon:continue-supervisor 명령어를 사용합니다:

php artisan horizon:pause-supervisor supervisor-1php artisan horizon:continue-supervisor supervisor-1

Horizon 프로세스의 현재 상태를 확인하려면 horizon:status 명령어를 사용합니다:

php artisan horizon:status

특정 supervisor가 유지할 워커 프로세스 수를 지정하려면 horizon:supervisors 명령어를 사용합니다:

php artisan horizon:supervisors supervisor-1 5

Horizon 프로세스를 정상적으로 종료하려면 horizon:terminate 명령어를 사용합니다. 현재 처리 중인 Job이 완료된 후 종료됩니다:

php artisan horizon:terminate

Horizon 배포

실제 서버에 Horizon을 배포할 때는 프로세스 모니터를 사용해 php artisan horizon 프로세스를 감시하고, 예기치 않게 종료된 경우 자동으로 재시작되도록 설정해야 합니다. 새 코드를 배포할 때는 Horizon 프로세스를 종료하여 프로세스 모니터가 재시작하면서 변경된 코드가 반영되도록 해야 합니다.

Supervisor 설정

프로덕션 환경에서 가장 널리 사용되는 프로세스 모니터는 Supervisor입니다. 아래는 Supervisor를 사용해 Horizon을 관리하는 예시 설정 파일입니다. 실제 환경에 맞게 경로를 조정하세요:

[program:horizon] process_name=%(program_name)s command=php /var/www/html/artisan horizon autostart=true autorestart=true user=www-data redirect_stderr=true stdout_logfile=/var/www/html/storage/logs/horizon.log stopwaitsecs=3600

WARNING

stopwaitsecs 값은 가장 오래 실행될 수 있는 Job의 실행 시간보다 커야 합니다. 그렇지 않으면 Supervisor가 Job이 완료되기 전에 프로세스를 강제 종료할 수 있습니다.

Forge / Vapor를 사용한 배포

Laravel Forge를 사용한다면 Forge에서 Horizon 데몬을 직접 관리할 수 있습니다. Forge 대시보드에서 Horizon을 데몬으로 등록하면 Supervisor 설정 없이도 자동으로 관리됩니다.

Laravel Vapor와 같은 서버리스 환경에서는 Horizon이 지원되지 않습니다. Vapor를 사용한다면 Laravel 큐 워커를 직접 사용하세요.

태그

Horizon에서는 메일, 브로드캐스트 이벤트, 알림, 큐에 등록된 이벤트 리스너 등을 포함한 Job에 "태그"를 붙일 수 있습니다. 이 태그를 활용하면 대시보드에서 특정 조건의 Job을 쉽게 검색하고 필터링할 수 있습니다.

Horizon은 대부분의 경우 Job에 사용된 Eloquent 모델을 감지해 자동으로 태그를 붙입니다. 예를 들어, 다음과 같은 Job이 있다면:

<?php namespace App\Jobs; use App\Models\Video; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class RenderVideo implements ShouldQueue { use Queueable; public function __construct( public Video $video, ) {} public function handle(): void { // ... } }

이 Job이 id가 1인 Video 모델과 함께 큐에 추가되면 Horizon은 자동으로 App\Models\Video:1이라는 태그를 붙입니다.

Horizon이 자동으로 태그를 붙이는 것 외에, Job 클래스에 tags 메서드를 직접 정의해 원하는 태그를 지정할 수도 있습니다:

<?php namespace App\Jobs; use App\Models\Video; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class RenderVideo implements ShouldQueue { use Queueable; public function __construct( public Video $video, ) {} /** * Job에 붙일 태그 목록 반환 * * @return array<int, string> */ public function tags(): array { return ['render', 'video:' . $this->video->id]; } }

이벤트 리스너에 수동으로 태그 붙이기

큐에 등록된 이벤트 리스너의 태그를 가져올 때, Horizon은 자동으로 이벤트 인스턴스를 tags 메서드에 전달합니다. 이를 활용해 이벤트 데이터를 기반으로 태그를 정의할 수 있습니다:

<?php namespace App\Listeners; use App\Events\VideoCreated; use Illuminate\Contracts\Queue\ShouldQueue; class SendVideoNotification implements ShouldQueue { /** * 리스너에 붙일 태그 목록 반환 * * @return array<int, string> */ public function tags(VideoCreated $event): array { return ['video:' . $event->video->id]; } }

알림

WARNING

Horizon에서 Slack이나 SMS 알림을 설정할 때는 관련 알림 채널의 사전 요구사항을 먼저 확인하세요.

특정 큐의 대기 시간이 너무 길어질 때 알림을 받고 싶다면, Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo, Horizon::routeSmsNotificationsTo 메서드를 사용하세요. 이 메서드들은 App\Providers\HorizonServiceProviderboot 메서드에서 호출하면 됩니다:

/** * 서비스 부트스트랩 */ public function boot(): void { parent::boot(); Horizon::routeSmsNotificationsTo('010-1234-5678'); Horizon::routeMailNotificationsTo('admin@example.com'); Horizon::routeSlackNotificationsTo('slack-webhook-url', '#큐-알림'); }

알림 대기 시간 임계값 설정

"대기 시간이 너무 길다"고 판단하는 기준은 config/horizon.phpwaits 옵션에서 설정합니다. 각 연결과 큐 조합별로 임계값(초)을 지정할 수 있습니다:

'waits' => [ 'redis:critical' => 30, // critical 큐는 30초 이상 대기 시 알림 'redis:default' => 60, // default 큐는 60초 이상 대기 시 알림 'redis:batch' => 120, // batch 큐는 120초 이상 대기 시 알림 ],

메트릭

Horizon 대시보드에는 Job과 큐의 대기 시간, 처리량 정보를 보여주는 메트릭 그래프가 있습니다. 이 그래프를 채우려면 애플리케이션의 스케줄러를 통해 Horizon의 snapshot Artisan 명령어를 5분마다 실행하도록 설정해야 합니다:

use Illuminate\Support\Facades\Schedule; Schedule::command('horizon:snapshot')->everyFiveMinutes();

실패한 Job 삭제

실패한 Job을 삭제하려면 horizon:forget 명령어를 사용합니다. 삭제할 Job의 ID나 UUID를 인자로 전달합니다:

php artisan horizon:forget 5

실패한 Job을 모두 삭제하려면 --all 옵션을 사용합니다:

php artisan horizon:forget --all

큐에서 Job 비우기

애플리케이션의 기본 큐에 있는 모든 Job을 삭제하려면 horizon:clear Artisan 명령어를 사용합니다:

php artisan horizon:clear

특정 큐의 Job만 삭제하려면 queue 옵션으로 큐 이름을 지정합니다:

php artisan horizon:clear --queue=emails

Horizon

목차

소개

NOTE

Laravel Horizon을 사용하기 전에 먼저 Laravel의 기본 큐 서비스에 익숙해지는 것을 권장합니다. Horizon은 기본 큐 기능을 확장하는 도구이므로, 큐의 핵심 개념을 모르는 상태에서 시작하면 혼란스러울 수 있습니다.

Laravel Horizon은 Laravel의 Redis 기반 큐를 위한 대시보드와 코드 기반 설정 도구입니다. Horizon을 사용하면 Job 처리량, 실행 시간, 실패한 Job 등 큐 시스템의 주요 지표를 한눈에 모니터링할 수 있습니다.

Horizon을 도입하면 모든 큐 워커 설정을 단일 설정 파일에서 관리할 수 있습니다. 이 파일을 버전 관리(Git 등)에 포함해두면, 배포 시 큐 워커를 쉽게 확장하거나 변경할 수 있어 인프라 관리가 훨씬 편리해집니다.

Horizon

설치

WARNING

Laravel Horizon은 큐 백엔드로 Redis를 사용해야 합니다. 따라서 애플리케이션의 config/queue.php 파일에서 큐 연결이 redis로 설정되어 있는지 확인하세요. 현재 Horizon은 Redis Cluster와 호환되지 않습니다.

Composer를 이용해 Horizon을 프로젝트에 설치합니다:

composer require laravel/horizon

설치 후, horizon:install Artisan 명령으로 Horizon의 에셋을 배포합니다:

php artisan horizon:install

설정

에셋 배포가 완료되면 config/horizon.php 파일이 생성됩니다. 이 파일에서 큐 워커 프로세스의 동작 방식을 세부적으로 조정할 수 있습니다. 각 옵션에는 설명이 포함되어 있으므로, 한 번씩 살펴보는 것을 권장합니다.

WARNING

Horizon은 내부적으로 horizon이라는 이름의 Redis 연결을 사용합니다. 이 이름은 예약어이므로, database.php의 Redis 연결 이름이나 horizon.phpuse 옵션 값으로 절대 사용하지 마세요.

Content Security Policy (CSP) Nonce

Content Security Policy를 적용 중이고, Horizon의 스크립트·스타일 태그에 nonce 속성을 추가하고 싶다면 Horizon::cspNonce 메서드를 사용하세요. 요청마다 새로운 nonce가 할당되어야 하므로, 미들웨어 안에서 호출하는 것이 적합합니다:

use Closure; use Illuminate\Http\Request; use Laravel\Horizon\Horizon; use Symfony\Component\HttpFoundation\Response; public function handle(Request $request, Closure $next): Response { Horizon::cspNonce('csp-nonce'); return $next($request); }

이 미들웨어는 config/horizon.phpmiddleware 옵션에 추가합니다:

'middleware' => [ 'web', App\Http\Middleware\AddHorizonCspNonce::class, ],

환경(Environments) 설정

설치 후 가장 먼저 살펴봐야 할 설정은 environments 옵션입니다. 이 옵션은 애플리케이션이 실행될 환경별로 워커 프로세스 옵션을 정의하는 배열입니다. 기본적으로 productionlocal 환경이 포함되어 있으며, 필요에 따라 환경을 자유롭게 추가할 수 있습니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, ], ], 'local' => [ 'supervisor-1' => [ 'maxProcesses' => 3, ], ], ],

어떤 환경에도 매칭되지 않을 때 사용할 와일드카드 환경(*)을 정의할 수도 있습니다:

'environments' => [ // ... '*' => [ 'supervisor-1' => [ 'maxProcesses' => 3, ], ], ],

Horizon을 시작하면 현재 실행 중인 환경에 맞는 워커 설정이 자동으로 적용됩니다. 환경은 APP_ENV 환경 변수 값을 기준으로 결정됩니다. 예를 들어, 기본 local 환경은 워커 프로세스를 3개 실행하고, production 환경은 최대 10개까지 실행하도록 설정되어 있습니다.

WARNING

horizon 설정 파일의 environments 섹션에는 Horizon을 실행할 모든 환경에 대한 항목이 반드시 포함되어 있어야 합니다.

슈퍼바이저(Supervisors)

기본 설정 파일을 보면 각 환경에 하나 이상의 "슈퍼바이저"를 정의할 수 있음을 알 수 있습니다. 기본값은 supervisor-1이지만 이름은 자유롭게 변경할 수 있습니다. 슈퍼바이저는 워커 프로세스 그룹을 감시하고, 큐 간 워커 배분을 담당합니다.

큐마다 다른 밸런싱 전략이나 워커 수를 적용하고 싶다면, 환경 내에 슈퍼바이저를 여러 개 정의하면 됩니다.

점검 모드(Maintenance Mode)

애플리케이션이 점검 모드일 때는 Horizon이 큐 Job을 처리하지 않습니다. 점검 모드 중에도 Job을 처리해야 한다면, 슈퍼바이저 설정에 force 옵션을 true로 지정하세요:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'force' => true, ], ], ],

기본값(Default Values)

기본 설정 파일에는 defaults 옵션이 있습니다. 이 옵션에 슈퍼바이저의 기본값을 정의해 두면, 각 환경의 슈퍼바이저 설정에 자동으로 병합됩니다. 환경마다 동일한 설정을 반복해서 작성하지 않아도 되므로 설정을 간결하게 유지할 수 있습니다.

대시보드 접근 제어

Horizon 대시보드는 /horizon 라우트로 접근할 수 있습니다. 기본적으로 local 환경에서만 접근이 허용됩니다. 비-local 환경에서의 접근은 app/Providers/HorizonServiceProvider.php에 정의된 인가 게이트(authorization gate)로 제어됩니다. 필요에 따라 이 게이트를 수정해 접근 권한을 제한하세요:

/** * Horizon 게이트를 등록합니다. * * 이 게이트는 비-local 환경에서 Horizon에 접근할 수 있는 사용자를 결정합니다. */ protected function gate(): void { Gate::define('viewHorizon', function (User $user) { return in_array($user->email, [ 'admin@example.com', // 접근을 허용할 이메일 주소 ]); }); }

인증 방식 커스터마이징

Laravel은 게이트 클로저에 인증된 사용자를 자동으로 주입합니다. 만약 IP 제한 등 별도의 방법으로 Horizon을 보호하고 있어 로그인이 필요 없는 상황이라면, 클로저 시그니처를 function (User $user = null)로 변경해 인증을 강제하지 않도록 설정하세요.

최대 Job 시도 횟수

NOTE

이 옵션을 조정하기 전에 Laravel의 기본 큐 서비스와 시도 횟수(attempts) 개념에 먼저 익숙해지는 것을 권장합니다.

슈퍼바이저 설정에서 Job의 최대 시도 횟수를 정의할 수 있습니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'tries' => 10, ], ], ],

NOTE

이 옵션은 Artisan 큐 처리 명령의 --tries 플래그와 동일한 역할을 합니다.

WithoutOverlapping이나 RateLimited 같은 미들웨어는 시도 횟수를 소모하므로, 이러한 미들웨어를 사용할 때는 tries 값을 적절히 조정하거나, Job 클래스에 $tries 프로퍼티를 정의하세요.

tries 옵션을 설정하지 않으면 Horizon은 기본적으로 1회만 시도합니다. 단, Job 클래스에 $tries가 정의되어 있다면 그 값이 우선 적용됩니다.

tries 또는 $tries0으로 설정하면 시도 횟수에 제한이 없어집니다. 무한 재시도로 인한 문제를 방지하려면 Job 클래스의 $maxExceptions 프로퍼티로 허용 예외 횟수를 제한하는 것을 권장합니다.

Job 타임아웃

슈퍼바이저 수준에서 timeout 값을 설정하면, 워커 프로세스가 Job을 실행할 수 있는 최대 시간(초)을 제한할 수 있습니다. 제한 시간을 초과하면 해당 Job은 강제 종료되고, 큐 설정에 따라 재시도되거나 실패로 처리됩니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'timeout' => 60, ], ], ],

WARNING

auto 밸런싱 전략을 사용할 때, Horizon은 스케일 다운 시 진행 중인 워커를 "멈춘(hanging)" 상태로 간주하고 Horizon 타임아웃이 지나면 강제 종료합니다. Horizon 타임아웃은 반드시 개별 Job의 타임아웃보다 길게 설정해야 하며, 그렇지 않으면 실행 중인 Job이 중간에 강제 종료될 수 있습니다. 또한 timeout 값은 config/queue.phpretry_after 값보다 적어도 몇 초 이상 짧게 설정해야 합니다. 그렇지 않으면 같은 Job이 두 번 처리될 수 있습니다.

Job 백오프(Backoff)

슈퍼바이저 수준에서 backoff 값을 설정하면, 처리되지 않은 예외가 발생했을 때 Horizon이 Job을 재시도하기 전에 대기하는 시간(초)을 지정할 수 있습니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'backoff' => 10, ], ], ],

지수 백오프(exponential backoff)가 필요하다면 backoff 값에 배열을 사용하세요. 아래 예시에서는 1차 재시도는 1초, 2차는 5초, 3차 이후는 10초 간격으로 대기합니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'backoff' => [1, 5, 10], ], ], ],

기타 워커 옵션

tries, timeout, backoff 외에도 각 슈퍼바이저는 워커 프로세스의 동작 방식과 자동 재시작 조건을 제어하는 여러 옵션을 지원합니다. 장시간 실행되는 프로세스의 메모리 누수 방지를 위해 주기적으로 워커를 재시작하는 것이 좋은 관행입니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'memory' => 128, 'maxJobs' => 1000, 'maxTime' => 3600, 'sleep' => 3, 'rest' => 0, 'nice' => 0, ], ], ],
  • memory: 워커 프로세스 하나가 사용할 수 있는 최대 메모리(MB)입니다. 이 한도를 초과하면 워커가 재시작됩니다. 기본값은 128입니다.
  • maxJobs: 워커가 재시작 전 처리할 최대 Job 수입니다. 0이면 처리 수 기준으로 재시작하지 않습니다. 기본값은 0입니다.
  • maxTime: 워커가 재시작 전 실행할 최대 시간(초)입니다. 0이면 시간 기준으로 재시작하지 않습니다. 기본값은 0입니다.
  • sleep: 처리할 Job이 없을 때 다음 폴링까지 대기하는 시간(초)입니다. 기본값은 3입니다.
  • rest: 각 Job 처리 사이에 쉬는 시간(초)입니다. 기본값은 0입니다.
  • nice: 워커 프로세스의 스케줄링 우선순위(niceness)입니다. 값이 높을수록 우선순위가 낮아집니다. 기본값은 0입니다.

Job 숨기기(Silenced Jobs)

특정 Job을 "완료된 Job" 목록에 표시하고 싶지 않을 때는 해당 Job을 숨길 수 있습니다. config/horizon.phpsilenced 옵션에 숨길 Job의 클래스명을 추가하세요:

'silenced' => [ App\Jobs\ProcessPodcast::class, ],

개별 클래스 외에도 태그 기반으로 Job을 숨길 수 있습니다. 공통 태그를 가진 여러 Job을 한 번에 숨길 때 유용합니다:

'silenced_tags' => [ 'notifications' ],

설정 파일 대신, Job 클래스가 Laravel\Horizon\Contracts\Silenced 인터페이스를 구현하게 하는 방법도 있습니다. 이 인터페이스를 구현한 Job은 silenced 배열에 등록되지 않아도 자동으로 숨겨집니다:

use Laravel\Horizon\Contracts\Silenced; class ProcessPodcast implements ShouldQueue, Silenced { use Queueable; // ... }

밸런싱 전략

각 수퍼바이저는 하나 이상의 큐를 처리할 수 있습니다. Laravel의 기본 큐 시스템과 달리, Horizon은 워커 프로세스 배분 방식을 세 가지 전략 중에서 선택할 수 있습니다: auto, simple, false.

Auto 밸런싱

auto 전략은 기본값으로, 각 큐의 현재 작업 부하에 따라 워커 프로세스 수를 자동으로 조정합니다. 예를 들어 notifications 큐에 1,000개의 대기 중인 Job이 있고 default 큐가 비어 있다면, Horizon은 notifications 큐가 처리될 때까지 해당 큐에 더 많은 워커를 할당합니다.

auto 전략을 사용할 때는 minProcessesmaxProcesses 옵션을 함께 설정할 수 있습니다:

  • minProcesses: 큐별 최소 워커 프로세스 수입니다. 1 이상이어야 합니다.
  • maxProcesses: 모든 큐를 합산한 워커 프로세스의 최대 총 수입니다. 일반적으로 큐 수 × minProcesses 값보다 크게 설정하는 것이 좋습니다. 0으로 설정하면 수퍼바이저가 프로세스를 생성하지 않습니다.

다음 예시는 큐마다 최소 1개의 프로세스를 유지하고, 전체 워커를 최대 10개까지 확장하도록 설정합니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ 'connection' => 'redis', 'queue' => ['default', 'notifications'], 'balance' => 'auto', 'autoScalingStrategy' => 'time', 'minProcesses' => 1, 'maxProcesses' => 10, 'balanceMaxShift' => 1, 'balanceCooldown' => 3, ], ], ],

autoScalingStrategy 옵션은 Horizon이 워커를 추가로 배분하는 기준을 결정합니다. 두 가지 방식 중 선택할 수 있습니다:

  • time: 큐를 모두 처리하는 데 걸리는 예상 총 시간을 기준으로 워커를 배분합니다.
  • size: 큐에 쌓인 Job의 총 개수를 기준으로 워커를 배분합니다.

balanceMaxShiftbalanceCooldown 값은 Horizon이 워커 수를 얼마나 빠르게 조정하는지를 제어합니다. 위 예시에서는 3초마다 최대 1개의 프로세스를 생성하거나 제거합니다. 애플리케이션의 특성에 맞게 자유롭게 조정하세요.

큐 우선순위와 Auto 밸런싱

auto 전략을 사용할 때 Horizon은 큐 간 엄격한 우선순위를 보장하지 않습니다. 수퍼바이저 설정에서 큐를 나열한 순서는 워커 배분에 영향을 주지 않습니다. 대신 autoScalingStrategy에 따라 큐 부하를 기준으로 워커를 동적으로 배분합니다.

예를 들어 아래 설정에서 high 큐가 먼저 나열되어 있더라도, default 큐보다 우선적으로 처리되지는 않습니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'queue' => ['high', 'default'], 'minProcesses' => 1, 'maxProcesses' => 10, ], ], ],

큐 간 우선순위를 명시적으로 지정하고 싶다면, 수퍼바이저를 여러 개로 분리해서 리소스를 직접 할당하세요:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'queue' => ['default'], 'minProcesses' => 1, 'maxProcesses' => 10, ], 'supervisor-2' => [ // ... 'queue' => ['images'], 'minProcesses' => 1, 'maxProcesses' => 1, ], ], ],

이 설정에서 default 큐는 최대 10개의 프로세스까지 확장될 수 있고, images 큐는 최대 1개로 제한됩니다. 큐마다 독립적으로 확장 규모를 조정할 수 있습니다.

NOTE

CPU를 많이 소모하는 무거운 Job은 maxProcesses를 낮게 설정한 전용 큐에 할당하는 것이 좋습니다. 그렇지 않으면 해당 Job들이 시스템 리소스를 과도하게 점유할 수 있습니다.

Simple 밸런싱

simple 전략은 지정된 큐들 사이에 워커 프로세스를 균등하게 분배합니다. 이 전략에서는 워커 수가 자동으로 조정되지 않으며, processes 옵션에 지정한 고정 수의 프로세스를 사용합니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'queue' => ['default', 'notifications'], 'balance' => 'simple', 'processes' => 10, ], ], ],

위 예시에서는 총 10개의 프로세스를 두 큐에 균등하게 배분하여 각 큐에 5개씩 할당됩니다.

큐별로 워커 수를 세밀하게 제어하고 싶다면, 수퍼바이저를 여러 개로 분리하세요:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'queue' => ['default'], 'balance' => 'simple', 'processes' => 10, ], 'supervisor-notifications' => [ // ... 'queue' => ['notifications'], 'balance' => 'simple', 'processes' => 2, ], ], ],

이 설정에서는 default 큐에 10개, notifications 큐에 2개의 프로세스가 할당됩니다.

밸런싱 없음

balance 옵션을 false로 설정하면, Horizon은 Laravel의 기본 큐 시스템처럼 나열된 순서대로 큐를 엄격하게 처리합니다. 단, Job이 쌓이기 시작하면 워커 프로세스 수는 자동으로 조정됩니다:

'environments' => [ 'production' => [ 'supervisor-1' => [ // ... 'queue' => ['default', 'notifications'], 'balance' => false, 'minProcesses' => 1, 'maxProcesses' => 10, ], ], ],

위 예시에서는 default 큐의 Job이 항상 notifications 큐보다 먼저 처리됩니다. 예를 들어 default에 1,000개, notifications에 10개의 Job이 있다면, Horizon은 default의 모든 Job을 처리한 뒤에야 notifications의 Job을 처리합니다.

minProcessesmaxProcesses 옵션으로 Horizon의 워커 프로세스 확장 범위를 제어할 수 있습니다:

  • minProcesses: 전체 최소 워커 프로세스 수입니다. 1 이상이어야 합니다.
  • maxProcesses: Horizon이 확장할 수 있는 전체 워커 프로세스의 최대 수입니다.

Horizon

Horizon 업그레이드

Horizon의 새로운 메이저 버전으로 업그레이드할 때는 업그레이드 가이드를 반드시 꼼꼼히 확인하시기 바랍니다.

Horizon 실행

config/horizon.php 설정 파일에서 슈퍼바이저와 워커 설정을 마쳤다면, horizon Artisan 명령어로 Horizon을 시작할 수 있습니다. 이 명령어 하나로 현재 환경에 맞게 설정된 모든 워커 프로세스가 함께 실행됩니다:

php artisan horizon

horizon:pausehorizon:continue 명령어로 Horizon 프로세스를 일시 중지하거나 재개할 수 있습니다:

php artisan horizon:pausephp artisan horizon:continue

특정 Horizon 슈퍼바이저만 선택적으로 일시 중지하거나 재개하려면 horizon:pause-supervisorhorizon:continue-supervisor 명령어를 사용하세요:

php artisan horizon:pause-supervisor supervisor-1php artisan horizon:continue-supervisor supervisor-1

현재 Horizon 프로세스의 상태는 horizon:status 명령어로 확인할 수 있습니다:

php artisan horizon:status

특정 Horizon 슈퍼바이저의 상태를 확인하려면 horizon:supervisor-status 명령어를 사용하세요:

php artisan horizon:supervisor-status supervisor-1

Horizon 프로세스를 안전하게 종료하려면 horizon:terminate 명령어를 사용하세요. 현재 처리 중인 Job이 모두 완료된 후 Horizon이 종료됩니다:

php artisan horizon:terminate

Horizon 자동 재시작 (로컬 개발 환경)

로컬 개발 환경에서는 horizon:listen 명령어를 사용하면 코드가 변경될 때 Horizon을 수동으로 재시작하지 않아도 됩니다. 이 기능을 사용하려면 로컬 환경에 Node.js가 설치되어 있어야 하며, 파일 감시 라이브러리인 Chokidar도 프로젝트에 추가해야 합니다:

npm install --save-dev chokidar

Chokidar 설치 후 아래 명령어로 Horizon을 시작하면 파일 변경 시 자동으로 재시작됩니다:

php artisan horizon:listen

Docker나 Vagrant 환경에서 실행할 때는 --poll 옵션을 추가하세요:

php artisan horizon:listen --poll

감시할 디렉터리와 파일은 config/horizon.phpwatch 옵션으로 설정할 수 있습니다:

'watch' => [ 'app', 'bootstrap', 'config', 'database', 'public/**/*.php', 'resources/**/*.php', 'routes', 'composer.lock', '.env', ],

NOTE

horizon:listen은 개발 편의를 위한 기능입니다. 운영 서버에서는 아래에서 설명하는 Supervisor와 같은 프로세스 모니터를 사용해 Horizon을 관리하세요.

Horizon 배포

실제 운영 서버에 Horizon을 배포할 때는 프로세스 모니터를 설정하여 php artisan horizon 명령어를 지속적으로 감시하고, 예기치 않게 종료될 경우 자동으로 재시작되도록 해야 합니다. 구체적인 설정 방법은 아래에서 설명합니다.

애플리케이션을 배포할 때는 먼저 Horizon 프로세스를 종료하여 프로세스 모니터가 이를 재시작하면서 변경된 코드를 반영하도록 합니다:

php artisan horizon:terminate

Supervisor 설치

Supervisor는 Linux 운영체제에서 사용하는 프로세스 모니터로, horizon 프로세스가 중단되면 자동으로 재시작해 줍니다. Ubuntu에서는 다음 명령어로 설치할 수 있으며, 다른 배포판에서는 해당 패키지 매니저를 사용하세요:

sudo apt-get install supervisor

NOTE

Supervisor 설정이 번거롭게 느껴진다면, 백그라운드 프로세스 관리를 대신 처리해 주는 Laravel Cloud 사용을 고려해 보세요.

Supervisor 설정

Supervisor 설정 파일은 일반적으로 서버의 /etc/supervisor/conf.d 디렉터리에 저장됩니다. 이 디렉터리에 원하는 수만큼 설정 파일을 만들어 프로세스 감시 방식을 지정할 수 있습니다. 예를 들어, horizon 프로세스를 시작하고 감시하는 horizon.conf 파일을 다음과 같이 작성할 수 있습니다:

[program:horizon] process_name=%(program_name)s command=php /home/forge/example.com/artisan horizon autostart=true autorestart=true user=forge redirect_stderr=true stdout_logfile=/home/forge/example.com/horizon.log stopwaitsecs=3600

stopwaitsecs 값은 가장 오래 실행되는 Job의 처리 시간(초)보다 반드시 크게 설정해야 합니다. 이 값이 너무 작으면 Supervisor가 Job 처리가 완료되기 전에 프로세스를 강제 종료할 수 있습니다.

WARNING

위 예시는 Ubuntu 기반 서버를 기준으로 합니다. 운영체제에 따라 Supervisor 설정 파일의 위치나 확장자가 다를 수 있으니, 사용 중인 서버의 문서를 참고하세요.

Supervisor 시작

설정 파일을 작성했다면 아래 명령어로 Supervisor 설정을 갱신하고 감시 프로세스를 시작하세요:

sudo supervisorctl rereadsudo supervisorctl updatesudo supervisorctl start horizon

NOTE

Supervisor에 대한 자세한 내용은 Supervisor 공식 문서를 참고하세요.

태그

Horizon은 Job, Mailable, 브로드캐스트 이벤트, 알림, 큐 이벤트 리스너 등 다양한 큐 객체에 태그를 붙일 수 있습니다. 특히 Job에 Eloquent 모델이 포함되어 있으면, Horizon이 자동으로 태그를 생성해줍니다.

예를 들어 아래와 같은 Job이 있다고 가정합니다:

<?php namespace App\Jobs; use App\Models\Video; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; class RenderVideo implements ShouldQueue { use Queueable; /** * 새 Job 인스턴스를 생성합니다. */ public function __construct( public Video $video, ) {} /** * Job을 실행합니다. */ public function handle(): void { // ... } }

id1App\Models\Video 인스턴스와 함께 이 Job이 디스패치되면, Horizon은 자동으로 App\Models\Video:1이라는 태그를 붙입니다. Horizon이 Job의 프로퍼티에서 Eloquent 모델을 감지하면, 모델의 클래스명과 기본 키(primary key)를 조합하여 태그를 생성하기 때문입니다.

use App\Jobs\RenderVideo; use App\Models\Video; $video = Video::find(1); RenderVideo::dispatch($video);

Job에 태그 직접 지정하기

태그를 직접 제어하고 싶다면, 큐 객체 클래스에 tags 메서드를 정의하면 됩니다:

class RenderVideo implements ShouldQueue { /** * Job에 할당할 태그 목록을 반환합니다. * * @return array<int, string> */ public function tags(): array { return ['render', 'video:'.$this->video->id]; } }

이벤트 리스너에 태그 직접 지정하기

큐 이벤트 리스너의 경우, Horizon은 tags 메서드를 호출할 때 이벤트 인스턴스를 자동으로 인자로 전달합니다. 덕분에 이벤트 데이터를 태그에 포함시킬 수 있습니다:

class SendRenderNotifications implements ShouldQueue { /** * 리스너에 할당할 태그 목록을 반환합니다. * * @return array<int, string> */ public function tags(VideoRendered $event): array { return ['video:'.$event->video->id]; } }

알림

WARNING

Slack 또는 SMS 알림을 설정하기 전에, 해당 알림 채널의 사전 요구사항을 반드시 확인하세요.

특정 큐의 대기 시간이 너무 길어질 때 알림을 받고 싶다면, Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo, Horizon::routeSmsNotificationsTo 메서드를 활용할 수 있습니다. 이 메서드들은 애플리케이션의 App\Providers\HorizonServiceProviderboot 메서드 안에서 호출하면 됩니다.

/** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { parent::boot(); Horizon::routeSmsNotificationsTo('15556667777'); Horizon::routeMailNotificationsTo('example@example.com'); Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel'); }

알림 대기 시간 임계값 설정

"긴 대기"로 판단하는 기준 시간(초)은 config/horizon.php 설정 파일의 waits 옵션에서 조정할 수 있습니다. 연결(connection)과 큐(queue) 조합별로 임계값을 개별 지정할 수 있으며, 별도로 정의하지 않은 조합은 기본값인 60초가 적용됩니다.

'waits' => [ 'redis:critical' => 30, // critical 큐는 30초 초과 시 알림 'redis:default' => 60, // default 큐는 60초 초과 시 알림 'redis:batch' => 120, // batch 큐는 120초 초과 시 알림 ],

특정 큐의 임계값을 0으로 설정하면, 해당 큐에 대한 긴 대기 알림이 비활성화됩니다.

메트릭

Horizon은 Job과 큐의 대기 시간 및 처리량 정보를 제공하는 메트릭 대시보드를 포함하고 있습니다. 이 대시보드에 데이터를 채우려면, routes/console.php 파일에서 Horizon의 horizon:snapshot Artisan 명령이 5분마다 실행되도록 스케줄을 등록해야 합니다:

use Illuminate\Support\Facades\Schedule; Schedule::command('horizon:snapshot')->everyFiveMinutes();

메트릭 그래프에 Horizon이 보관할 스냅샷 수는 config/horizon.php 설정 파일의 metrics.trim_snapshots 옵션으로 조정할 수 있습니다. 이 옵션은 보관 기간이 아닌 스냅샷 개수를 기준으로 제한하므로, 실제 보관 기간은 horizon:snapshot 명령의 실행 주기에 따라 달라집니다. 예를 들어 5분마다 실행하고 trim_snapshots를 24로 설정하면 약 2시간치 데이터가 유지됩니다:

'metrics' => [ 'trim_snapshots' => [ 'job' => 24, 'queue' => 24, ], ],

수집된 메트릭 데이터를 모두 삭제하려면 horizon:clear-metrics Artisan 명령을 실행하세요:

php artisan horizon:clear-metrics

Horizon

실패한 Job 삭제

실패한 Job을 삭제하려면 horizon:forget 명령어를 사용하세요. 이 명령어는 실패한 Job의 ID 또는 UUID를 인수로 받습니다:

php artisan horizon:forget 5

실패한 Job을 전부 삭제하려면 --all 옵션을 함께 사용하세요:

php artisan horizon:forget --all

Horizon

큐에서 Job 삭제하기

애플리케이션의 기본 큐에 있는 모든 Job을 삭제하려면 horizon:clear Artisan 명령어를 사용하세요:

php artisan horizon:clear

특정 큐의 Job만 삭제하려면 queue 옵션을 함께 지정하면 됩니다:

php artisan horizon:clear --queue=emails

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 7월 31일