Claude Code cron式リファレンスと7日失効・ジッターの仕様
Claude Codeのスケジュールタスクが受け付けるcron式の書き方、発火時刻に乗るジッター、繰り返しタスクが7日で失効する仕様をまとめます。
cron式の書式と、受け付けない記法
CronCreateが受け付けるのは、分 時 日 月 曜日の5フィールドです。どのフィールドにも、ワイルドカード*、単一値5、ステップ*/15、範囲1-5、カンマ区切りのリスト1,15,30が使えます。
| cron式 | 意味 |
|---|---|
*/5 * * * * | 意味5分ごと |
0 * * * * | 意味毎時00分 |
7 * * * * | 意味毎時07分 |
0 9 * * * | 意味毎日ローカル時刻9時 |
0 9 * * 1-5 | 意味平日のローカル時刻9時 |
0 9,12,18 * * * | 意味毎日9時・12時・18時の3回 |
30 14 15 3 * | 意味3月15日のローカル時刻14時30分 |
曜日は0と7が日曜、6が土曜です。L・W・?のような拡張構文と、MON・JANのような名前の別名は使えません。数字で書きます。
月末を表すLが無いので、「毎月の最終日」はcron式だけでは書けません。どの月にも存在する日は28日までなので、月末に近い日で足りるなら28を指定します。
時刻はすべてローカルのタイムゾーンで解釈されます。0 9 * * *は、Claude Codeを動かしている環境の9時です。UTCの9時ではありません。タイムゾーンを指定するフィールドは無く、秒のフィールドもありません。
日付と曜日を両方書くと「または」になる
日と曜日の両方に値を入れると、どちらか一方に一致した日に発火します。vixie-cronと同じ仕様で、「毎月15日、かつ月曜日」にはなりません。
日と曜日の指定で変わる発火日
日だけ指定
毎月1日の9時だけ発火します。曜日は見ません。
曜日だけ指定
毎週月曜の9時だけ発火します。日にちは見ません。
両方を指定
「1日」または「月曜」のどちらかに当たる日に発火します。2026年のカレンダーで数えると、3月・8月・11月が6回で、ほかの月は5回です。
片方だけを絞りたいときは、もう片方を*のままにします。「第1月曜だけ」のような条件は、日と曜日の組み合わせでは表せません。
毎分発火する書き方と、間隔が崩れるステップ
分のフィールドを*のままにすると、発火回数が想定より多くなります。* 9 * * *は「9時台に1回」ではなく、9時00分から9時59分まで毎分の発火です。時刻を絞るときは、分に単一値を入れます。
平日の日中だけ15分おきに動かすなら、ステップと範囲を同じ式の中で組み合わせて*/15 9-17 * * 1-5と書きます。深夜と週末は動きません。
ステップは、フィールドの先頭から数えます。*/7 * * * *は毎時の0分、7分、14分と進み、56分のあと、次の時の0分に戻ります。56分から0分までは4分しかなく、7分おきにはなりません。
60を割り切れない間隔は、こうして崩れます。*/15は0分・15分・30分・45分で、60を割り切るため間隔が揃います。/loopに7mや90mのようにきれいなステップにならない間隔を渡すと、近い間隔に丸められ、Claudeがどれにしたかを知らせます。秒を渡した場合は、cronの最小単位が1分なので、分に切り上げられます。
発火が定刻にならない理由 — ジッターの規則
多数のセッションが同じ時刻にAPIへ集中しないよう、スケジューラは発火時刻にずれを足します。ずれはタスクIDから決まる固定の値で、同じタスクは毎回同じだけずれます。
タスクの種類で変わるジッター
繰り返しタスク
予定時刻から最大30分遅れます。間隔が1時間より短いタスクは、間隔の半分が上限です。毎時:00のタスクは、:00から:30のどこかで発火します。
単発タスク
毎時00分か30分に予定したときだけ、最大90秒早く発火します。分をずらせば、このジッターは付きません。
繰り返しタスクの遅れは、何分に予定しても最大30分まで乗ります。「毎朝9時ちょうどに動かしたい」という用途には、3 9 * * *のような書き方でも応えられません。
間隔を省略した自己ペースの/loopには、このジッターの規則は適用されません。Claudeが毎回、1分から1時間の間で次の待ち時間を決めます。ただし7日の失効は、自己ペースの/loopにも同じように掛かります。固定間隔の/loopと単発のリマインダーの扱いは、Claude Codeの/loopと一回きりのリマインダーにあります。
繰り返しタスクは7日で消える。再開時に戻るもの・戻らないもの
繰り返しタスクは、作成から7日で期限切れになります。期限が来ると最後にもう一度だけ発火し、そのままタスク自体が削除されます。置き忘れたループが動き続けないための上限です。
月に1回や年に1回の式は、この上限と相性が悪くなります。次の該当日が作成から7日より先なら、その日を待たずに期限が来ます。0 9 1 * *のような月次の式が、これに当たります。
claude --resumeやclaude --continueでセッションを再開すると、CronCreateで作ったタスクが復元されます。復元されないものは次のとおりです。
再開しても戻らないタスク
期限切れの繰り返しタスク
作成から7日を過ぎたものは、再開しても戻りません。
時刻を過ぎた単発タスク
予定の時刻が再開前に過ぎていた単発タスクです。時刻がこれからの単発タスクは復元されます。
自己ペースの /loop
もう一度
/loopを実行して、始め直します。バックグラウンドのBashとmonitor
再開時に復元されることはありません。
7日を超えて動かしたいときの選択肢は2つです。期限が来る前にタスクをキャンセルして作り直すか、セッションに縛られないRoutinesやDesktopのスケジュールタスクへ移します。移す先を選ぶときは最短の間隔も効きます。Routinesは1時間、Desktopのスケジュールタスクと/loopは1分です。Routinesはクラウドで動くので、自分のマシンの電源を入れておく必要がありません。Desktopのスケジュールタスクは自分のマシンで動き、セッションを開いたままにしておく必要はありません。承認ゲート付きの在庫アラートにスケジュールタスクを使った例は、SquareとCoworkで在庫確認と品切れアラートを自動化するにあります。
フィーチャーフラグの取得を止めている環境では、セッションをまたいで残したいタスクがプロジェクトの.claude/scheduled_tasks.jsonに保存されます。.claudeディレクトリかこのファイルがシンボリックリンクだと、スケジュールせずにエラーを返します。保存されたタスクは、作成したプロジェクトのフォルダでだけ動きます。新しいworktreeなど別のフォルダへファイルをコピーしても、一覧には出ますが実行されません。そのフォルダで作り直します。
発火しないときの切り分け
タスクが動かないときは、まずスケジューラそのものが止まっていないかを見ます。CLAUDE_CODE_DISABLE_CRON=1が設定されていると、CronCreate・CronList・CronDeleteと/loopが使えなくなり、登録済みのタスクも発火しなくなります。ほかの無効化系フラグは、Claude Codeの環境変数リファレンスにまとめています。
次に、仕様として発火しない状況かを見ます。
- Claude Codeが起動していて、アイドルのときしか発火しません。ターミナルを閉じたりセッションを終了したりすると止まります。
- 長い応答の最中に予定時刻を過ぎても、取り戻しの発火はありません。アイドルに戻った時点で1回だけ発火し、逃した回数ぶんが連続して実行されることはありません。
- バックグラウンドへ切り替えたセッションには、
/loopのタスクが引き継がれます。ターミナルが無くても動き続けます。
仕様の範囲で説明できない報告も、GitHubのissueに上がっています。どれも個別の再現報告で、公式の説明とは別のものです。
- 一回きりのタスクに、すでに過ぎた時刻を指定すると、次回の同じ日時、つまり翌年へ繰り越されると報告されています。
CronListは年を表示しないので、有効なタスクのように見えます(issue #82360)。30 14 15 3 *のような日付固定の式を、時刻を過ぎてから作るときが当てはまります。 - 長時間の
/loopセッションで、コンテキストの圧縮と再開が起きたあと、約103分のあいだ発火が止まったという報告があります。自己ペースの待機、登録済みの繰り返しcron、バックグラウンドの完了通知が、同時に止まったとされています(issue #89248)。 - セッションをバックグラウンドへ切り替えたあと、
/loop 3mのタスクがアイドル中には発火せず、ユーザーが発言した直後にだけ1回発火するようになったという報告もあります(issue #96531)。
発火が止まったと感じたら、CronListに載っていることだけで安心せず、実際に発火した時刻を見ます。
管理に使う3つのツールと50件の上限
自然言語で頼めば、Claudeが裏側で次のツールを呼びます。「今あるスケジュールタスクを教えて」と聞けば一覧が、「デプロイ確認のジョブを取り消して」と頼めば取り消しが走ります。
| ツール | 役割 |
|---|---|
CronCreate | 役割5フィールドのcron式・実行するプロンプト・繰り返すか一回きりかを指定して登録する |
CronList | 役割セッション内の全タスクを、ID・スケジュール・プロンプト付きで一覧する |
CronDelete | 役割IDを指定してタスクを取り消す |
各タスクには8文字のIDが付き、CronDeleteに渡して取り消します。1セッションに置けるタスクは合計50件までです。/loopのタスクも、CronListの一覧に並ぶ同じタスクです。
発火したときに投げるプロンプトへスラッシュコマンドを書く場合は、Claudeが自分で呼べるスキルだけが実行されます。/permissions・/model・/clearのような組み込みコマンドや、disable-model-invocation: trueのスキル、MCPのプロンプトは、実行されずに文字列のままClaudeへ届きます。
Stop hookから未発火のタスクを見る — session_crons
Stop hookの入力には、background_tasksと並んでsession_cronsという配列が含まれます。セッションが終わったのか、バックグラウンドの作業や発火を待って止まっているだけなのかを、hook側で見分けるためのフィールドです。タスクが何も登録されていなければ、配列は空です。
| フィールド | 内容 |
|---|---|
id | 内容cronタスクのID |
schedule | 内容cron式(例: 0 9 * * 1-5) |
recurring | 内容単発ならfalse、繰り返すならtrue |
prompt | 内容発火時に投げるプロンプト(1000文字で切り詰め) |
拾われるのはCronCreateのタスクだけではありません。ScheduleWakeup(自己ペースの/loopが毎回の待機を決めるために呼ぶツール)と/loopで登録された待機も、同じ配列に入ります。バックグラウンドでこの待機が過ぎて止まったときは、Claude Codeのバックグラウンドで/loopが止まるで再開できます。SubagentStop hookにも同じsession_cronsが渡されますが、配列の範囲はサブエージェントではなく、親セッションです。Stop hookの入力全体はClaude Code Hooks完全ガイドにあります。
まとめ
時刻の正確さが要る処理にスケジュールタスクは向きません。7日を超えて続けたい処理や、マシンを閉じても動かしたい処理は、最初からRoutinesで組むという選択肢があります。