Skip to main content

タスクスケジューリングとは

従来、サーバーで定期実行が必要なタスクごとに cron エントリを手書きする必要がありました。 しかしこの方法ではスケジュール定義がソースコード外に存在するため、バージョン管理できず、確認・変更のたびに SSH ログインが必要になります。 Laravelのスケジューラを使うと、アプリケーション内でスケジュールを流暢に定義できます。 サーバーに登録する cron エントリは1行だけで済み、スケジュール定義はコードとともにバージョン管理されます。 スケジュールは routes/console.php に定義するのが標準的なスタイルです。
schedule:list Artisanコマンドで、定義済みのタスク一覧と次回実行予定時刻を確認できます。

スケジューラーの実行フロー

スケジュールの定義方法

スケジュールの定義は routes/console.php に記述します。 bootstrap/app.php の withSchedule メソッドを使って定義する方法もあります。

スケジュール可能なタスクの種類

Artisanコマンドのスケジュール

command メソッドでArtisanコマンドをスケジュールします。 コマンド名またはクラス名で指定できます。
クロージャで定義したArtisanコマンドにも、定義の直後にスケジュールメソッドをチェーンできます。

キュージョブのスケジュール

job メソッドでキュージョブをスケジュールします。 クロージャを使わずにジョブをキューに積む便利な方法です。
キュー名や接続先を指定することもできます。

シェルコマンドのスケジュール

exec メソッドでOSコマンドを実行します。

クロージャのスケジュール

call メソッドで任意のPHPクロージャをスケジュールします。
__invoke メソッドを持つ Invocable オブジェクトも渡せます。

スケジュール頻度の設定

主な頻度メソッド

よく使う頻度メソッドを以下に示します。

cron式で直接指定

cron メソッドで cron 式を直接指定することもできます。

頻度と曜日の組み合わせ

頻度メソッドと曜日の制約を組み合わせて、より細かいスケジュールを作れます。

タイムゾーンの設定

timezone メソッドで個別タスクのタイムゾーンを指定できます。
すべてのタスクに共通のタイムゾーンを設定したい場合は、config/app.php の schedule_timezone を使います。
夏時間(サマータイム)が適用されるタイムゾーンを使う場合、切り替えのタイミングでタスクが2回実行されるか、まったく実行されないことがあります。 可能な限り UTC を使うことを推奨します。

条件制約

when / skip

when はクロージャが true を返した場合のみタスクを実行します。 skip はその逆で、true を返した場合にスキップします。

environments

environments メソッドで特定の環境でのみ実行するよう制限できます。

時刻の制約

between / unlessBetween で実行時間帯を制限できます。

曜日の制約

重複防止

デフォルトでは、前回のタスクがまだ実行中でも次の実行が開始されます。 withoutOverlapping を使うと、前の実行が終わるまで次の実行を待機させられます。
ロックの有効期限(分)を指定することもできます。デフォルトは24時間です。
withoutOverlapping はアプリケーションのキャッシュを使ってロックを管理します。 タスクが予期せぬ問題でスタックした場合は schedule:clear-cache でロックを解除できます。

複数サーバーでの実行制御

複数サーバーでスケジューラが動いている場合、onOneServer を使うことで1台のサーバーだけでタスクを実行できます。
この機能を使うには、アプリケーションのデフォルトキャッシュドライバを database、memcached、dynamodb、または redis に設定し、すべてのサーバーが同じキャッシュサーバーに接続している必要があります。

onOneServer() による分散実行制御フロー

タスクのグループ化

複数のタスクに同じ設定を適用する場合は group メソッドを使ってまとめられます。

バックグラウンド実行

同じ時刻にスケジュールされたタスクは、デフォルトでは定義順に順番に実行されます。 長時間かかるタスクがあると後続のタスクの開始が遅れます。 runInBackground を使うと、タスクをバックグラウンドで並列実行できます。
runInBackground は command と exec メソッドでのみ使用できます。

メンテナンスモード

アプリケーションがメンテナンスモードのとき、スケジュールタスクは実行されません。 メンテナンスモード中でも強制的に実行させたい場合は evenInMaintenanceMode を使います。

メンテナンスモードの対応フロー

スケジューラの一時停止

コードを変更せずにスケジューラを一時停止できます。
停止中でも特定のタスクだけ実行し続けたい場合は evenWhenPaused を使います。 ヘルスチェックやシステム監視など、メンテナンス中でも継続が必要なタスクに役立ちます。

出力のハンドリング

ファイルへの出力

sendOutputTo でタスクの出力をファイルに保存できます。
appendOutputTo を使うと、既存のファイルに追記します。

メールへの出力

emailOutputTo でタスクの出力をメールで送信できます。 事前にLaravelのメール設定が必要です。
失敗時のみメールを送る場合は emailOutputOnFailure を使います。

タスクフック

before / after メソッドで、タスクの実行前後に処理を挿入できます。
成功・失敗時のフックは onSuccess / onFailure で定義します。

サーバーへのデプロイ

1

cron エントリを追加する

サーバーの crontab に以下の1行を追加するだけで、Laravelのスケジューラが毎分実行されます。
crontab -e コマンドで編集できます。
2

スケジューラの動作を確認する

定義済みタスクの一覧と次回実行時刻を確認します。
Laravel Cloud を使うと、cron の設定なしにスケジュールタスクを管理できます。

ローカル開発での実行

ローカル環境では cron を使わず、schedule:work コマンドでスケジューラを常時起動できます。
このコマンドはフォアグラウンドで動作し、毎分スケジューラを呼び出します。Ctrl+C で停止するまで動き続けます。

サブ分スケジュール(1分未満の頻度)

通常の cron は1分が最小単位ですが、Laravelでは1秒単位のスケジュールも設定できます。
サブ分タスクが定義されている場合、schedule:run はその分が終わるまで動き続けて、すべてのサブ分タスクを処理します。
サブ分タスクはキュージョブやバックグラウンドコマンドに処理を委譲することを推奨します。 タスク自体が長時間かかると、後続のサブ分タスクの実行が遅れるためです。
デプロイ中に実行中の schedule:run を中断するには、デプロイスクリプトに以下を追加します。

よく使うコマンドまとめ

最終更新日 2026年4月7日