Claude Code cron式リファレンスと7日失効・ジッターの仕様
Claude Codeのスケジュールタスクが受け付けるcron式の書き方、発火時刻に乗るジッター、繰り返しタスクが7日で失効する仕様をまとめます。
Claude Codeが受け付けるcron式の書式
CronCreateは標準的な5フィールドのcron式を受け付けます。書式は分 時 日 月 曜日です。
| フィールド | 指定できる形式 | 例 |
|---|---|---|
| 分・時・日・月・曜日共通 | 指定できる形式ワイルドカード* | 例* * * * * |
| 同上 | 指定できる形式単一値 | 例5 9 * * * |
| 同上 | 指定できる形式ステップ | 例*/15 * * * * |
| 同上 | 指定できる形式範囲 | 例9-17 * * * * |
| 同上 | 指定できる形式カンマ区切りリスト | 例0 9,12,18 * * * |
よく使う例を挙げます。
| cron式 | 意味 |
|---|---|
*/5 * * * * | 意味5分ごと |
0 * * * * | 意味毎時00分 |
7 * * * * | 意味毎時07分 |
0 9 * * * | 意味毎日ローカル時刻9時 |
0 9 * * 1-5 | 意味平日のローカル時刻9時 |
30 14 15 3 * | 意味3月15日のローカル時刻14時30分 |
曜日フィールドは0または7が日曜、6が土曜です。L・W・?のような拡張構文や、MON・JANのような名前エイリアスはサポート対象外です。数字での指定に統一する必要があります。
「月末」を表す構文が無い点も見落としやすいところです。Lが使えないため、月末日を指定したい場合は28や30のように具体的な日にちを直接書くしかありません。月によって末日が変わる月をまたいで厳密に「最終日」を扱いたい場合、cron式単体では表現できない制約として認識しておく必要があります。
日と曜日を両方制約した場合は、どちらか一方に一致すれば発火します。これはvixie-cronと同じ仕様です。「毎月15日、かつ月曜日」を意図して両方指定しても、実際には「15日か月曜日のどちらか」になる点は見落としやすいところです。片方だけを絞りたい場合は、もう片方をワイルドカードのままにします。
具体例で比べると分かりやすくなります。0 9 1 * *は日にちだけを見るので毎月1日の9時に発火し、0 9 * * 1は曜日だけを見るので毎週月曜の9時に発火します。両方を指定した0 9 1 * 1は「1日か月曜日のどちらか」が条件になり、月によっては月に5回以上発火することもあります。日にちと曜日のどちらか片方は必ずワイルドカードにしておくのが、意図しない発火を避ける基本です。
時刻はすべてローカルのタイムゾーンで解釈されます。0 9 * * *はUTCの9時ではなく、Claude Codeを動かしている環境のローカル時刻で9時を意味します。
ステップと範囲を組み合わせて書く
分・時のフィールドはワイルドカードのまま使うと発火回数が想定より多くなりがちです。* 9 * * *は「9時台に発火」ではなく、9時00分から9時59分まで毎分発火する式です。単一値かステップに置き換えるのが安全です。
平日の日中だけ15分おきに確認したい場合は、ステップと範囲を組み合わせて*/15 9-17 * * 1-5のように書きます。これは「平日の9時から17時台まで、15分刻みで発火する」という意味になり、深夜や週末は動きません。範囲とステップは同じフィールド内で自由に組み合わせられます。
ジッターの仕組み — 発火時刻はぴったりではない
多数のセッションが同じ時刻に一斉にAPIへアクセスしないよう、スケジューラは発火時刻に決まったずれ(ジッター)を加えます。
- 繰り返しタスク: 予定時刻から最大30分遅れて発火することがあります。実行間隔が1時間未満のタスクでは、その間隔の半分までが上限になります。毎時00分に予定した時間ごとのジョブなら、00分から30分までの間のどこかで発火し得ます。
- 単発タスク: 毎時00分・30分ちょうどに予定した場合に限り、最大90秒前倒しで発火することがあります。
このずれはタスクIDから決まる決定論的な値です。同じタスクなら毎回同じだけずれ、ランダムではありません。厳密な時刻にこだわるなら、00分・30分以外の分を指定します。たとえば0 9 * * *の代わりに3 9 * * *を使えば、単発タスクのジッターは適用されません。
裏を返すと、スケジュールも文面もまったく同じタスクを一度CronDeleteで消してCronCreateし直すと、作り直すたびにタスクIDが変わるため、ずれ方も変わると考えられます。発火が早すぎる・遅すぎると感じたときに、時刻自体は変えずに作り直すとずれ方が変化する場合があります。
なお、間隔を省略した自己ペースの/loopはClaude自身が毎回待ち時間を決めるため、00分・30分ちょうどに当たること自体がまれで、実務上ジッターを意識する場面はほとんどありません。固定間隔の/loopや一回きりのリマインダーの挙動はClaude Codeの/loopと一回きりのリマインダーで扱っています。
繰り返しタスクは7日で自動的に失効する
繰り返しタスクは、作成から7日で自動的に期限切れになります。期限が来ると最後にもう一度だけ発火してから、タスク自体が削除されます。これは、うっかり作ったまま忘れたループが際限なく動き続ける事態を防ぐための仕様です。
7日を超えて動かし続けたい場合の選択肢は2つあります。期限が来る前にタスクをキャンセルして再作成するか、そもそもセッションに縛られないRoutinesやDesktopのスケジュールタスクに切り替えます。どちらもセッションの生死やこの7日ルールに影響されずに動きます。
単発タスクにはこの7日失効の仕組み自体がありません。発火すれば1回で終わり、発火する前にセッションが消えれば一緒に消えます。
スケジュールタスクを管理する3つのツール
自然言語で頼めばClaudeが裏側で次のツールを呼び出します。
| ツール | 役割 |
|---|---|
CronCreate | 役割5フィールドのcron式・実行するプロンプト・繰り返すか一回きりかを指定して新規登録する |
CronList | 役割セッション内の全スケジュールタスクをID・スケジュール・プロンプト付きで一覧する |
CronDelete | 役割IDを指定してタスクを取り消す |
各タスクには8文字のIDが振られ、CronDeleteに渡すことで取り消せます。1セッションに置けるスケジュールタスクは合計50件までです。/loopのタスクも一回きりのリマインダーも、この上限を分け合います。
hooksからスケジュールタスクを見る — session_crons
Stop hookを組んでいる場合、session_cronsという配列でセッション内の未発火タスクを直接参照できます。background_tasksと並んで、Stop hookの入力に含まれるフィールドです。
| フィールド | 内容 |
|---|---|
id | 内容cronタスクのID |
schedule | 内容cron式(例: 0 9 * * 1-5) |
recurring | 内容一回きりならfalse、繰り返すならtrue |
prompt | 内容発火時に投げられるプロンプト(1000文字で切り詰め) |
session_cronsが拾うのはCronCreateだけではありません。ScheduleWakeup(自己ペース/loopが使う内部ツール)や/loop本体で登録したタスクも、区別なく同じ配列に含まれます。「セッションがもう完了しているのか、それともバックグラウンドの発火待ちで止まっているだけなのか」をhook側で見分けたい場面で使えます。Stop hookの入力全体の構造はClaude Code Hooks完全ガイドにまとめています。
発火の優先度と見逃しへの対応
スケジューラは毎秒、期限が来たタスクをチェックし、低優先度でキューに入れます。発火するのはターンとターンの合間だけで、Claudeが応答している最中に予定時刻が来た場合は現在のターンが終わるまで待たされます。
見逃した回の埋め合わせはありません。長時間の応答で予定時刻を何度も過ぎても、アイドルに戻った時点で1回だけ実行されます。逃した回数分がまとめて実行されるわけではない点は、頻繁な間隔で回すタスクほど気に留めておく価値があります。
スケジューラそのものを無効化する
環境変数CLAUDE_CODE_DISABLE_CRON=1を設定すると、スケジューラそのものが丸ごと止まります。CronCreate・CronList・CronDeleteツールと/loopが使えなくなり、すでに登録済みのタスクも発火しなくなります。企業環境で外部との定期通信を一律止めたい場合などに使う設定で、Claude Codeの環境変数リファレンスにほかの無効化系フラグとあわせてまとめています。
よくあるつまずき
日付と曜日を両方指定したら意図と違う日にも発火した — vixie-cron方式ではどちらか一方に一致すれば発火します。片方だけを効かせたいなら、もう片方はワイルドカードのままにします。
MONやLのような書き方でエラーになった — 名前エイリアスや拡張構文はサポート対象外です。数字での曜日指定(0〜7)と標準の5フィールド構文に統一します。
毎時00分に設定した繰り返しタスクが00分ちょうどに来ない — 仕様どおりです。最大30分のジッターが乗ります。厳密な時刻が必要なら00分・30分以外を指定します。
7日経ったら勝手に消えた — 繰り返しタスクの仕様です。長期運用にはRoutinesかDesktopのスケジュールタスクを使います。
よくある質問
秒単位でcron式を書けますか
書けません。CronCreateが受け付けるのは分単位の5フィールド構文で、秒を指定するフィールドはそもそも存在しません。
タイムゾーンを指定できますか
cron式自体にタイムゾーンを指定する項目はありません。すべての時刻は、Claude Codeを動かしている環境のローカルタイムゾーンで一律に解釈されます。
ジッターを完全になくす方法はありますか
繰り返しタスクのジッターを完全に消す方法はありません。単発タスクに限り、発火分を00分・30分以外にすることでそのジッターを避けられます。
session_cronsはhooksを組んでいなくても見られますか
hooksの入力フィールドなので、Stop hookかSubagentStop hookを設定していないと参照できません。一覧の確認だけなら、Claudeに自然言語で「スケジュールタスクを教えて」と頼む方が簡単です。
1日に複数回、決まった時刻だけ発火させたい場合はどう書きますか
カンマ区切りのリストが使えます。0 9,12,18 * * *のように分・時のフィールドに複数の値を並べれば、毎日9時・12時・18時の3回だけ発火する式を1つにまとめられます。ステップ指定と違い、値と値の間隔が不均等でもかまいません。
50件の上限に達するとどうなりますか
上限に達すると新しいタスクは登録できません。不要になったタスクをCronDeleteで削除してから、あらためて登録し直します。
まとめ
Claude Codeのスケジュールタスクは標準的な5フィールドcron式を使い、日付・曜日を両方指定するとどちらか一方に一致すれば発火するvixie-cron方式です。発火時刻には決定論的なジッターが乗るため、厳密な時刻が要る場合は00分・30分以外の分を指定します。長期運用にはRoutinesかDesktopのスケジュールタスクに切り替えます。