본문 바로가기

스케줄링

업데이트됨

번역일: 2026년 9월 17일

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

원문 수정
2026년 9월 17일
번역 갱신
2026년 9월 17일

스케줄링

소개

예전에는 서버에서 실행해야 하는 작업마다 cron 설정 항목을 일일이 작성해야 했습니다. 하지만 이 방식은 금방 골칫거리가 됩니다. 스케줄 정의가 소스 코드에 포함되지 않기 때문에, 기존에 등록된 cron 항목을 확인하거나 새 항목을 추가하려면 매번 서버에 SSH로 접속해야 하죠.

Laravel의 명령어 스케줄러는 서버의 예약 작업을 관리하는 완전히 새로운 방식을 제공합니다. 스케줄러를 사용하면 Laravel 애플리케이션 내부에서 유연하고 직관적인 문법으로 스케줄을 정의할 수 있습니다. 그리고 서버에는 오직 하나의 cron 항목만 등록하면 됩니다. 스케줄 정의는 보통 애플리케이션의 routes/console.php 파일에 작성합니다.

스케줄 정의하기

애플리케이션의 모든 예약 작업은 routes/console.php 파일에 정의할 수 있습니다. 먼저 예제를 하나 살펴보겠습니다. 아래 예제는 매일 자정에 클로저를 호출하도록 예약합니다. 클로저 내부에서는 데이터베이스 쿼리를 실행하여 테이블의 데이터를 삭제합니다.

<?php use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schedule; Schedule::call(function () { DB::table('recent_users')->delete(); })->daily();

클로저를 사용하는 방법 외에도, 호출 가능한 객체(invokable object)를 스케줄링할 수도 있습니다. 호출 가능한 객체란 __invoke 메서드를 가진 단순한 PHP 클래스를 말합니다.

Schedule::call(new DeleteRecentUsers)->daily();

routes/console.php 파일은 명령어 정의만을 위한 용도로 남겨두고 싶다면, bootstrap/app.php 파일에서 withSchedule 메서드를 사용해 스케줄을 정의할 수도 있습니다. 이 메서드는 스케줄러 인스턴스를 인자로 받는 클로저를 전달받습니다.

use Illuminate\Console\Scheduling\Schedule; ->withSchedule(function (Schedule $schedule) { $schedule->call(new DeleteRecentUsers)->daily(); })

등록된 예약 작업 목록과 각 작업의 다음 실행 시각을 한눈에 확인하고 싶다면, schedule:list Artisan 명령어를 사용하세요.

php artisan schedule:list

Artisan 명령어 스케줄링

클로저 외에도 Artisan 명령어와 시스템 명령어도 예약할 수 있습니다. 예를 들어 command 메서드를 사용하면 명령어의 이름 또는 클래스를 기준으로 Artisan 명령어를 예약할 수 있습니다.

명령어의 클래스명을 사용해 스케줄링하는 경우, 명령어 실행 시 전달할 추가 커맨드라인 인자를 배열 형태로 함께 넘길 수 있습니다.

use App\Console\Commands\SendEmailsCommand; use Illuminate\Support\Facades\Schedule; Schedule::command('emails:send Taylor --force')->daily(); Schedule::command(SendEmailsCommand::class, ['Taylor', '--force'])->daily();

클로저로 정의한 Artisan 명령어 스케줄링

클로저로 정의된 Artisan 명령어를 예약하고 싶다면, 명령어 정의 뒤에 스케줄링 관련 메서드를 체이닝하면 됩니다.

Artisan::command('delete:recent-users', function () { DB::table('recent_users')->delete(); })->purpose('Delete recent users')->daily();

클로저 명령어에 인자를 전달해야 한다면, schedule 메서드에 인자를 넘겨주면 됩니다.

Artisan::command('emails:send {user} {--force}', function ($user) { // ... })->purpose('Send emails to the specified user')->schedule(['Taylor', '--force'])->daily();

큐 작업 스케줄링

job 메서드를 사용하면 큐에 등록되는 Job을 예약할 수 있습니다. call 메서드로 클로저를 작성해 직접 Job을 큐에 넣는 방식보다 훨씬 간편합니다.

use App\Jobs\Heartbeat; use Illuminate\Support\Facades\Schedule; Schedule::job(new Heartbeat)->everyFiveMinutes();

job 메서드에는 선택적으로 두 번째, 세 번째 인자를 전달할 수 있는데, 각각 Job을 큐에 넣을 때 사용할 큐 이름과 큐 커넥션을 지정합니다.

use App\Jobs\Heartbeat; use Illuminate\Support\Facades\Schedule; // "sqs" 커넥션의 "heartbeats" 큐로 Job을 디스패치합니다... Schedule::job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes();

셸 명령어 스케줄링

exec 메서드를 사용하면 운영체제에 직접 명령을 내릴 수 있습니다.

use Illuminate\Support\Facades\Schedule; Schedule::exec('node /home/forge/script.js')->daily();

스케줄 주기 옵션

지금까지 특정 주기로 작업을 실행하도록 설정하는 몇 가지 예시를 살펴봤습니다. 이 외에도 작업에 지정할 수 있는 다양한 실행 주기 옵션이 있습니다.

메서드설명
->cron('* * * * *');사용자가 지정한 cron 표현식으로 작업을 실행합니다.
->everySecond();매초마다 작업을 실행합니다.
->everyTwoSeconds();2초마다 작업을 실행합니다.
->everyFiveSeconds();5초마다 작업을 실행합니다.
->everyTenSeconds();10초마다 작업을 실행합니다.
->everyFifteenSeconds();15초마다 작업을 실행합니다.
->everyTwentySeconds();20초마다 작업을 실행합니다.
->everyThirtySeconds();30초마다 작업을 실행합니다.
->everyMinute();매분마다 작업을 실행합니다.
->everyTwoMinutes();2분마다 작업을 실행합니다.
->everyThreeMinutes();3분마다 작업을 실행합니다.
->everyFourMinutes();4분마다 작업을 실행합니다.
->everyFiveMinutes();5분마다 작업을 실행합니다.
->everyTenMinutes();10분마다 작업을 실행합니다.
->everyFifteenMinutes();15분마다 작업을 실행합니다.
->everyThirtyMinutes();30분마다 작업을 실행합니다.
->hourly();매시간마다 작업을 실행합니다.
->hourlyAt(17);매시간 17분에 작업을 실행합니다.
->everyOddHour($minutes = 0);홀수 시간마다 작업을 실행합니다.
->everyTwoHours($minutes = 0);2시간마다 작업을 실행합니다.
->everyThreeHours($minutes = 0);3시간마다 작업을 실행합니다.
->everyFourHours($minutes = 0);4시간마다 작업을 실행합니다.
->everySixHours($minutes = 0);6시간마다 작업을 실행합니다.
->daily();매일 자정에 작업을 실행합니다.
->dailyAt('13:00');매일 13:00에 작업을 실행합니다.
->twiceDaily(1, 13);매일 1시와 13시에 작업을 실행합니다.
->twiceDailyAt(1, 13, 15);매일 1시 15분과 13시 15분에 작업을 실행합니다.
->daysOfMonth([1, 10, 20]);매월 특정 날짜에 작업을 실행합니다.
->weekly();매주 일요일 00:00에 작업을 실행합니다.
->weeklyOn(1, '8:00');매주 월요일 8:00에 작업을 실행합니다.
->monthly();매월 1일 00:00에 작업을 실행합니다.
->monthlyOn(4, '15:00');매월 4일 15:00에 작업을 실행합니다.
->twiceMonthly(1, 16, '13:00');매월 1일과 16일 13:00에 작업을 실행합니다.
->lastDayOfMonth('15:00');매월 마지막 날 15:00에 작업을 실행합니다.
->quarterly();매 분기 첫날 00:00에 작업을 실행합니다.
->quarterlyOn(4, '14:00');매 분기 4일 14:00에 작업을 실행합니다.
->yearly();매년 1월 1일 00:00에 작업을 실행합니다.
->yearlyOn(6, 1, '17:00');매년 6월 1일 17:00에 작업을 실행합니다.
->timezone('America/New_York');작업에 적용할 타임존을 지정합니다.

이 메서드들은 특정 요일에만 실행되도록 하는 등, 더 세밀한 조건과 조합할 수 있습니다. 예를 들어 매주 월요일에만 실행되도록 예약할 수 있습니다.

use Illuminate\Support\Facades\Schedule; // 매주 월요일 13시에 한 번만 실행... Schedule::call(function () { // ... })->weekly()->mondays()->at('13:00'); // 평일 오전 8시부터 오후 5시까지 매시간 실행... Schedule::command('foo') ->weekdays() ->hourly() ->timezone('America/Chicago') ->between('8:00', '17:00');

추가로 사용할 수 있는 스케줄 제약 조건 목록은 아래와 같습니다.

메서드설명
->weekdays();평일에만 작업을 실행합니다.
->weekends();주말에만 작업을 실행합니다.
->sundays();일요일에만 작업을 실행합니다.
->mondays();월요일에만 작업을 실행합니다.
->tuesdays();화요일에만 작업을 실행합니다.
->wednesdays();수요일에만 작업을 실행합니다.
->thursdays();목요일에만 작업을 실행합니다.
->fridays();금요일에만 작업을 실행합니다.
->saturdays();토요일에만 작업을 실행합니다.
->days(array|mixed);지정한 요일에만 작업을 실행합니다.
->between($startTime, $endTime);지정한 시작 시각과 종료 시각 사이에만 작업을 실행합니다.
->unlessBetween($startTime, $endTime);지정한 시작 시각과 종료 시각 사이에는 작업을 실행하지 않습니다.
->when(Closure);주어진 조건식의 결과에 따라 작업 실행 여부를 결정합니다.
->environments($env);지정한 환경에서만 작업을 실행합니다.

요일 제약 조건

days 메서드를 사용하면 특정 요일에만 작업이 실행되도록 제한할 수 있습니다. 예를 들어 다음은 일요일과 수요일에만 매시간 실행되도록 예약하는 예제입니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('emails:send') ->hourly() ->days([0, 3]);

또는 요일을 숫자 대신 Illuminate\Console\Scheduling\Schedule 클래스에 정의된 상수를 사용해서 지정할 수도 있습니다.

use Illuminate\Support\Facades; use Illuminate\Console\Scheduling\Schedule; Facades\Schedule::command('emails:send') ->hourly() ->days([Schedule::SUNDAY, Schedule::WEDNESDAY]);

시간대 제약 조건

between 메서드를 사용하면 하루 중 특정 시간대에만 작업이 실행되도록 제한할 수 있습니다.

Schedule::command('emails:send') ->hourly() ->between('7:00', '22:00');

반대로 unlessBetween 메서드를 사용하면 특정 시간대에는 작업이 실행되지 않도록 제외할 수 있습니다.

Schedule::command('emails:send') ->hourly() ->unlessBetween('23:00', '4:00');

조건식 기반 제약 조건

when 메서드를 사용하면 주어진 조건식의 결과에 따라 작업 실행 여부를 제한할 수 있습니다. 즉, 클로저가 true를 반환하면 다른 제약 조건이 실행을 막지 않는 한 작업이 실행됩니다.

Schedule::command('emails:send')->daily()->when(function () { return true; });

skip 메서드는 when의 반대라고 볼 수 있습니다. skip 메서드에 전달한 클로저가 true를 반환하면 예약된 작업은 실행되지 않습니다.

Schedule::command('emails:send')->daily()->skip(function () { return true; });

when 메서드를 여러 번 체이닝한 경우, 모든 조건이 true를 반환해야만 예약된 명령어가 실행됩니다.

환경 제약 조건

environments 메서드를 사용하면 지정한 환경(APP_ENV 환경 변수로 정의됨)에서만 작업이 실행되도록 제한할 수 있습니다.

Schedule::command('emails:send') ->daily() ->environments(['staging', 'production']);

타임존

timezone 메서드를 사용하면 예약된 작업의 실행 시각을 지정한 타임존 기준으로 해석하도록 설정할 수 있습니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('report:generate') ->timezone('America/New_York') ->at('2:00');

모든 예약 작업에 동일한 타임존을 반복해서 지정하고 있다면, 애플리케이션의 app 설정 파일에 schedule_timezone 옵션을 정의하여 모든 스케줄에 일괄 적용할 수 있습니다.

'timezone' => 'UTC', 'schedule_timezone' => 'America/Chicago',

WARNING

일부 타임존은 일광절약시간제(썸머타임)를 적용합니다. 이런 시간 변경이 일어나는 시점에는 예약 작업이 두 번 실행되거나 아예 실행되지 않을 수 있습니다. 이러한 이유로, 가능하다면 타임존 기반 스케줄링은 피하는 것을 권장합니다.

작업 중복 실행 방지하기

기본적으로 예약된 작업은 이전 실행이 아직 끝나지 않았더라도 다음 스케줄이 되면 그대로 실행됩니다. 이를 막고 싶다면 withoutOverlapping 메서드를 사용하세요.

use Illuminate\Support\Facades\Schedule; Schedule::command('emails:send')->withoutOverlapping();

위 예제에서 emails:send Artisan 명령어는 이미 실행 중이 아닐 때만 매분 실행됩니다. withoutOverlapping 메서드는 특히 작업마다 실행 시간이 크게 달라서 정확히 얼마나 걸릴지 예측하기 어려운 경우에 유용합니다.

필요하다면 "중복 방지" 잠금이 몇 분 후에 만료될지도 지정할 수 있습니다. 기본값은 24시간입니다.

Schedule::command('emails:send')->withoutOverlapping(10);

withoutOverlapping 메서드는 내부적으로 애플리케이션의 캐시를 사용해 잠금을 얻습니다. 필요한 경우 schedule:clear-cache Artisan 명령어로 이 캐시 잠금을 초기화할 수 있습니다. 보통 예기치 못한 서버 문제로 작업이 멈춰버린 경우에만 이 명령어가 필요합니다.

하나의 서버에서만 작업 실행하기

WARNING

이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버로 database, memcached, dynamodb, redis 중 하나를 사용해야 합니다. 또한 모든 서버가 동일한 중앙 캐시 서버와 통신하고 있어야 합니다.

애플리케이션의 스케줄러가 여러 서버에서 동시에 실행되는 환경이라면, 특정 예약 작업이 오직 하나의 서버에서만 실행되도록 제한할 수 있습니다. 예를 들어 매주 금요일 밤에 새로운 리포트를 생성하는 예약 작업이 있다고 가정해봅시다. 스케줄러가 세 대의 워커 서버에서 동시에 실행되고 있다면, 이 작업이 세 서버 모두에서 실행되어 리포트가 세 번 생성되어 버립니다. 원치 않는 상황이죠.

작업이 오직 하나의 서버에서만 실행되도록 하려면, 작업을 정의할 때 onOneServer 메서드를 사용하세요. 가장 먼저 작업을 가져간 서버가 원자적(atomic) 잠금을 획득하여, 다른 서버들이 동시에 같은 작업을 실행하지 못하도록 막아줍니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('report:generate') ->fridays() ->at('17:00') ->onOneServer();

단일 서버 작업에 필요한 원자적 잠금을 얻을 때 사용할 캐시 저장소를 직접 지정하고 싶다면, useCache 메서드를 사용하세요.

Schedule::useCache('database');

단일 서버 Job에 이름 지정하기

같은 Job을 서로 다른 파라미터로 여러 번 디스패치하면서도, 각 조합마다 오직 하나의 서버에서만 실행되도록 하고 싶을 때가 있습니다. 이런 경우 name 메서드를 사용해 각 스케줄 정의에 고유한 이름을 부여하면 됩니다.

Schedule::job(new CheckUptime('https://laravel.com')) ->name('check_uptime:laravel.com') ->everyFiveMinutes() ->onOneServer(); Schedule::job(new CheckUptime('https://vapor.laravel.com')) ->name('check_uptime:vapor.laravel.com') ->everyFiveMinutes() ->onOneServer();

마찬가지로, 클로저를 단일 서버에서만 실행하고 싶다면 반드시 이름을 지정해야 합니다.

Schedule::call(fn () => User::resetApiRequestCount()) ->name('reset-api-request-count') ->daily() ->onOneServer();

백그라운드 작업

기본적으로 같은 시각에 실행되도록 예약된 여러 작업은 schedule 메서드에 정의된 순서대로 순차적으로 실행됩니다. 실행 시간이 오래 걸리는 작업이 있다면, 그로 인해 뒤에 정의된 작업들이 예상보다 훨씬 늦게 시작될 수 있습니다. 여러 작업을 동시에 병렬로 실행하고 싶다면 runInBackground 메서드를 사용하세요.

use Illuminate\Support\Facades\Schedule; Schedule::command('analytics:report') ->daily() ->runInBackground();

WARNING

runInBackground 메서드는 commandexec 메서드로 예약한 작업에만 사용할 수 있습니다.

점검 모드

애플리케이션이 점검 모드에 있는 동안에는 예약된 작업이 실행되지 않습니다. 서버에서 진행 중인 점검 작업을 예약 작업이 방해하지 않도록 하기 위한 안전장치입니다. 그럼에도 점검 모드에서 강제로 실행되어야 하는 작업이 있다면, 작업을 정의할 때 evenInMaintenanceMode 메서드를 호출하세요.

Schedule::command('emails:send')->evenInMaintenanceMode();

스케줄 작업 일시 중지하기

배포된 코드를 변경하지 않고도 schedule:pause Artisan 명령어를 사용해 예약 작업 처리를 임시로 중지할 수 있습니다.

php artisan schedule:pause

스케줄러가 일시 중지된 동안에는 어떤 예약 작업도 실행되지 않습니다. 다시 실행을 재개하려면 schedule:continue 명령어를 사용하세요.

php artisan schedule:continue

스케줄러가 일시 중지된 상태에서도 특정 작업만은 계속 실행되도록 하고 싶다면, 해당 작업에 evenWhenPaused 메서드를 지정하세요.

Schedule::command('emails:send')->evenWhenPaused();

스케줄 그룹

비슷한 설정을 공유하는 여러 예약 작업을 정의할 때는, Laravel의 스케줄 그룹 기능을 사용해 중복 설정을 줄일 수 있습니다. 작업을 그룹으로 묶으면 코드가 간결해지고 관련 작업들 간의 일관성도 유지할 수 있습니다.

스케줄 그룹을 만들려면, 원하는 설정 메서드들을 먼저 체이닝한 다음 group 메서드를 호출하세요. group 메서드는 해당 설정을 공유할 작업들을 정의하는 클로저를 인자로 받습니다.

use Illuminate\Support\Facades\Schedule; Schedule::daily() ->onOneServer() ->timezone('America/New_York') ->group(function () { Schedule::command('emails:send --force'); Schedule::command('emails:prune'); });

스케줄러 실행하기

지금까지 예약 작업을 정의하는 방법을 살펴봤습니다. 이제 실제 서버에서 이 작업들을 어떻게 실행하는지 알아보겠습니다. schedule:run Artisan 명령어는 등록된 모든 예약 작업을 검사하여, 서버의 현재 시각을 기준으로 실행이 필요한 작업이 있는지 판단합니다.

즉, Laravel 스케줄러를 사용하면 서버에는 schedule:run 명령어를 매분 실행하는 cron 항목 하나만 등록하면 됩니다. 서버에 cron 항목을 추가하는 방법을 모른다면, Laravel Cloud와 같이 예약 작업 실행을 대신 관리해주는 매니지드 플랫폼을 고려해보세요.

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

NOTE

국내 호스팅 환경(예: 카페24, NHN Cloud 등)의 관리 콘솔에서 cron 설정을 지원하는 경우가 많으니, SSH 접근이 제한적인 환경이라면 해당 콘솔의 크론탭 설정 기능을 활용해도 좋습니다.

1분 미만 주기의 스케줄 작업

대부분의 운영체제에서 cron 작업은 최소 1분 간격으로만 실행할 수 있습니다. 하지만 Laravel의 스케줄러는 이보다 훨씬 더 짧은 주기, 심지어 1초 단위로도 작업을 예약할 수 있습니다.

use Illuminate\Support\Facades\Schedule; Schedule::call(function () { DB::table('recent_users')->delete(); })->everySecond();

애플리케이션에 1분 미만 주기의 작업이 정의되어 있으면, schedule:run 명령어는 즉시 종료되지 않고 현재 분(minute)이 끝날 때까지 계속 실행됩니다. 이렇게 함으로써 해당 1분 동안 필요한 모든 짧은 주기의 작업을 실행할 수 있습니다.

1분 미만 주기의 작업이 예상보다 오래 걸리면 이후에 실행될 다른 짧은 주기 작업들이 지연될 수 있습니다. 따라서 실제 처리 로직은 큐 작업이나 백그라운드 명령어로 위임하는 것을 권장합니다.

use App\Jobs\DeleteRecentUsers; Schedule::job(new DeleteRecentUsers)->everyTenSeconds(); Schedule::command('users:delete')->everyTenSeconds()->runInBackground();

1분 미만 주기 작업 중단하기

1분 미만 주기의 작업이 정의되어 있으면 schedule:run 명령어는 실행이 시작된 그 1분이 끝날 때까지 계속 동작합니다. 이 때문에 애플리케이션을 배포하는 시점에는 이미 실행 중인 schedule:run 프로세스를 중단해야 할 필요가 있을 수 있습니다. 그렇지 않으면 이미 실행 중이던 프로세스가 배포 이전의 코드를 그대로 사용한 채 남은 시간을 계속 실행하게 됩니다.

실행 중인 schedule:run 프로세스를 중단하려면, 배포 스크립트에 schedule:interrupt 명령어를 추가하세요. 이 명령어는 애플리케이션 배포가 완료된 직후에 실행해야 합니다.

php artisan schedule:interrupt

로컬에서 스케줄러 실행하기

일반적으로 로컬 개발 환경에는 스케줄러용 cron 항목을 따로 등록하지 않습니다. 대신 schedule:work Artisan 명령어를 사용할 수 있습니다. 이 명령어는 포그라운드에서 실행되며, 명령어를 종료하기 전까지 매분마다 스케줄러를 호출합니다. 1분 미만 주기의 작업이 정의되어 있다면, 스케줄러는 각 1분 동안 계속 실행되면서 해당 작업들을 처리합니다.

php artisan schedule:work

작업 결과 출력

Laravel 스케줄러는 예약 작업이 만들어내는 출력 결과를 다루기 위한 다양한 편의 메서드를 제공합니다. 먼저, sendOutputTo 메서드를 사용하면 출력 내용을 파일로 저장하여 나중에 확인할 수 있습니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('emails:send') ->daily() ->sendOutputTo($filePath);

출력 내용을 파일에 덮어쓰지 않고 이어서 추가하고 싶다면 appendOutputTo 메서드를 사용하세요.

Schedule::command('emails:send') ->daily() ->appendOutputTo($filePath);

emailOutputTo 메서드를 사용하면 출력 결과를 원하는 이메일 주소로 보낼 수 있습니다. 출력 결과를 이메일로 보내기 전에 Laravel의 메일 서비스를 먼저 설정해야 합니다.

Schedule::command('report:generate') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('taylor@example.com');

예약된 Artisan 명령어나 시스템 명령어가 0이 아닌 종료 코드로 끝난 경우에만 출력 결과를 이메일로 받고 싶다면, emailOutputOnFailure 메서드를 사용하세요.

Schedule::command('report:generate') ->daily() ->emailOutputOnFailure('taylor@example.com');

WARNING

emailOutputTo, emailOutputOnFailure, sendOutputTo, appendOutputTo 메서드는 commandexec 메서드로 예약한 작업에서만 사용할 수 있습니다.

작업 훅

beforeafter 메서드를 사용하면 예약된 작업이 실행되기 전과 후에 실행할 코드를 지정할 수 있습니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('emails:send') ->daily() ->before(function () { // 작업이 곧 실행됩니다... }) ->after(function () { // 작업이 실행되었습니다... });

onSuccessonFailure 메서드를 사용하면 예약된 작업이 성공했을 때와 실패했을 때 각각 실행할 코드를 지정할 수 있습니다. 여기서 실패란 예약된 Artisan 명령어나 시스템 명령어가 0이 아닌 종료 코드로 끝난 경우를 의미합니다.

Schedule::command('emails:send') ->daily() ->onSuccess(function () { // 작업이 성공했습니다... }) ->onFailure(function () { // 작업이 실패했습니다... });

명령어의 출력 결과를 확인할 수 있다면, after, onSuccess, onFailure 훅의 클로저에서 $output 인자에 Illuminate\Support\Stringable 타입힌트를 지정하여 접근할 수 있습니다.

use Illuminate\Support\Stringable; Schedule::command('emails:send') ->daily() ->onSuccess(function (Stringable $output) { // 작업이 성공했습니다... }) ->onFailure(function (Stringable $output) { // 작업이 실패했습니다... });

URL 핑 보내기

pingBeforethenPing 메서드를 사용하면 작업이 실행되기 전이나 실행된 후에 스케줄러가 지정한 URL로 자동으로 핑을 보낼 수 있습니다. 이 기능은 Envoyer와 같은 외부 서비스에 예약 작업이 시작되거나 끝났음을 알려줄 때 유용합니다.

Schedule::command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);

pingOnSuccesspingOnFailure 메서드는 작업이 성공했을 때 또는 실패했을 때만 지정한 URL로 핑을 보냅니다. 여기서 실패란 예약된 Artisan 명령어나 시스템 명령어가 0이 아닌 종료 코드로 끝난 경우를 의미합니다.

Schedule::command('emails:send') ->daily() ->pingOnSuccess($successUrl) ->pingOnFailure($failureUrl);

pingBeforeIf, thenPingIf, pingOnSuccessIf, pingOnFailureIf 메서드는 주어진 조건이 true일 때만 지정한 URL로 핑을 보냅니다.

Schedule::command('emails:send') ->daily() ->pingBeforeIf($condition, $url) ->thenPingIf($condition, $url); Schedule::command('emails:send') ->daily() ->pingOnSuccessIf($condition, $successUrl) ->pingOnFailureIf($condition, $failureUrl);

이벤트

Laravel은 스케줄링 처리 과정 중에 다양한 이벤트를 발생시킵니다. 다음 이벤트에 대해 리스너를 정의할 수 있습니다.

이벤트 이름
Illuminate\Console\Events\ScheduledTaskStarting
Illuminate\Console\Events\ScheduledTaskFinished
Illuminate\Console\Events\ScheduledBackgroundTaskFinished
Illuminate\Console\Events\ScheduledTaskSkipped
Illuminate\Console\Events\ScheduledTaskFailed

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

번역일: 2026년 9월 17일