GitHub Actionsのscheduleは、YAMLに5フィールドのcronを1行書くだけで定期実行が始まります。ところが実運用に入った途端、指定した時刻に走らない、日本時間とずれる、しばらく放置していたら黙って止まっていた、という相談が並びます。いずれも障害ではなく仕様どおりの挙動で、先に知っていれば設計で吸収できるものばかりです。本記事では時刻起動だけに絞り、構文とタイムゾーンの扱い、遅延と欠落の実際、停止条件、そして定期実行に載せてよい処理の線引きまでを実装できる粒度で扱います。GitHub Actions自体の概要とワークフローの基本構造はGitHub Actionsでできること・使い方の解説に、pushやpull_requestを含むイベント全体の選び分けはトリガー(on)の設計解説に譲ります。
まとめ:定期実行の採否を決める3つの判断と結論
先に結論を書きます。判断は3つです。1つ目は「時刻をどの基準で書くか」。既定はUTCで、日本時間から9時間を引いた手計算になります。2026年3月の更新でcronと並べてtimezoneキーにIANAのタイムゾーン名を書けるようになったため、新規に組むならAsia/Tokyoを明示して手計算を消すほうが読み違いが減ります。
2つ目は「遅延をどこまで許容できるか」。scheduleは高負荷時に遅れ、負荷が十分に高ければキューに入ったジョブが破棄されることがあると公式に明記されています。毎時00分は最も混む時間帯なので、実務では00分を外して分をずらすのが基本形になるでしょう。
3つ目は「止まったときに誰が気づくか」。定期実行はワークフローファイルが既定ブランチに存在しなければ発火せず、パブリックリポジトリでは60日間リポジトリの活動が無いと自動的に無効化されます。通知の宛先はcronを最後に変更した人に紐づくため、担当者が異動した瞬間に無音になります。
迷ったときの初期値は、timezoneを明示した1日1回のジョブを、毎時00分を避けた分(たとえば17分)に置き、workflow_dispatchを併記して手動でも起動できる形にする構成です。定刻に走ることが業務要件になっている処理は、この時点で対象から外してください。
schedule構文の書き方:5つのフィールドと使える4種類の演算子
scheduleはPOSIXのcron構文に従います。ここで押さえるのは、フィールドの並び順、使える演算子、そしてGitHub Actionsが受け付けない書き方の3点です。
分・時・日・月・曜日の5フィールドを左から記述する順序と確認方法
フィールドは空白区切りで5つ、左から分(0〜59)、時(0〜23)、日(1〜31)、月(1〜12またはJAN〜DEC)、曜日(0〜6またはSUN〜SAT)の順に並びます。使える演算子は4種類です。アスタリスクは任意の値、カンマは値の列挙、ハイフンは範囲、スラッシュは間隔を表します。
on:
schedule:
- cron: '15 4,5 * * *'
この例は毎日UTCの4時15分と5時15分に走ります。30 4-6 * * * なら4時・5時・6時の各30分、20/15 * * * * なら毎時20分から15分刻みで20分・35分・50分の3回です。曜日と日を同時に指定したときの解釈は環境によって差が出やすいので、どちらか一方だけを使うほうが事故が減ります。
@dailyなどの非標準構文がサポート対象外になる仕様上の注意点
他のcron実装で使える @yearly、@monthly、@weekly、@daily、@hourly、@reboot は、GitHub Actionsでは非標準構文としてサポートされていません。手元のcrontabからコピーしてきた設定が動かない場合、まずここを疑ってください。@dailyのつもりなら 0 3 * * * のように5フィールドで書き直します。
最短間隔は5分・複数指定はgithub.event.scheduleで分岐
実行できる最短間隔は5分に1回です。*/1 * * * * と書いても毎分は走りません。分刻みの監視が要件なら、そもそもGitHub Actionsではなく常駐プロセスや専用の監視基盤を選ぶ判断になります。
1つのワークフローに複数のscheduleを並べることもできます。どのスケジュールで起動したかはgithub.event.scheduleコンテキストで判別でき、同じワークフロー内でステップの実行可否を切り替えられます。切り替えに使う式の評価規則はGitHub Actionsの条件分岐(if)|書く場所で変わるコンテキストと評価の規則を参照してください。
on:
schedule:
- cron: '0 21 * * 1-5'
- cron: '0 15 * * 6'
jobs:
batch:
runs-on: ubuntu-latest
steps:
- name: Weekday only
if: github.event.schedule != '0 15 * * 6'
run: echo weekday
なお短い間隔で回すほど実行時間の総量が増え、その分が課金対象の分数に積み上がります。5分間隔の常時稼働は無料枠を短期間で使い切る規模になるため、頻度を決める前に2026年改定後の分単価と無料枠の解説で費用感を確認しておくと判断を誤りません。
時刻の基準:UTC既定とtimezoneキーによる地域時刻の指定
定期実行で最も多い問い合わせが「9時間ずれる」です。基準時刻の扱いは2026年3月の更新で選択肢が増えており、新規と既存で書き方の推奨が変わります。
既定はUTCなので日本時間から9時間引いてcronへ記述する方法
timezoneを書かない場合、スケジュールはUTCで解釈されます。日本時間はUTC+9なので、日本時間の朝9時に走らせたいなら前日のUTC0時、つまり 0 0 * * * です。日本時間の朝6時なら 0 21 * * * となり、曜日指定を伴うときは日付が前日へずれる点に注意が要ります。日本時間の月曜朝6時は、UTCでは日曜の21時です。
timezoneキーにIANA名を書いて時差の手計算を省く指定方法
公式ドキュメントの2026年8月時点の記述では、cronと並べてtimezoneにIANAのタイムゾーン文字列を指定でき、その地域時刻でスケジュールが解釈されます。この指定は2026年3月の更新(GitHub Changelogの「Late March 2026 updates」)で入ったもので、日本語圏の解説記事の多くはまだUTC手計算のみを前提に書かれています。
on:
schedule:
- cron: '0 6 * * 1-5'
timezone: 'Asia/Tokyo'
この書き方なら「平日の朝6時」がそのままYAMLに現れるため、レビューで時差を暗算する必要がなくなります。引き継ぎ時の読み違いも防げる書式です。既存のUTC指定を一括で書き換える必要はありません。新規に足す定期ジョブはtimezoneを明示する方針に寄せておけば、後から入る担当者の負担を軽くできます。
夏時間で消える時刻が次の有効な時刻へ繰り上がる場合の挙動と注意点
夏時間を採用する地域をtimezoneに指定した場合、春の切り替えで存在しなくなる時刻に置いたスケジュールは、次の有効な時刻へ繰り上がります。公式の例では2時30分の指定が3時00分へ移ります。日本標準時は夏時間を持たないためAsia/Tokyoでは起きませんが、海外拠点の営業時間に合わせてAmerica/New_Yorkなどを指定するときは、年2回だけ実行時刻が動く前提で設計してください。
起動の遅延と欠落:毎時00分を避けて実行時刻を分散する設計判断
ここが定期実行を業務に組み込むときの分かれ目です。GitHub Actionsのscheduleは、定刻起動を保証する仕組みではありません。
高負荷時に起動が遅延しキュー中のジョブが破棄され得る条件と対策
公式ドキュメントは、scheduleイベントがワークフロー実行の高負荷時に遅延する可能性があり、高負荷の時間帯には毎時の開始時刻が含まれると明記しています。さらに負荷が十分に高い場合、キューに入ったジョブの一部が破棄されることがあるとも書かれています。遅延を減らす公式の推奨は、実行時刻を毎時の別の分へずらすことです。
現場での運用上の含意は2つあります。1つは、0 * * * * のようなちょうどの時刻を避け、17 * * * * のような半端な分に寄せること。もう1つは、処理を冪等に作り、1回飛んでも次回の実行で取り返せる形にしておくことです。前回実行時刻を保存して差分を処理する設計にしておけば、欠落は遅延と同じ扱いに落とせます。
定刻精度が要るなら外部からworkflow_dispatchを叩く
締め切りのある処理で分単位の精度が要求されるなら、起動の主導権をGitHub Actionsの外へ移す構成が現実解になります。外部のスケジューラからworkflow_dispatchのAPIを呼び、GitHub Actions側は実行環境としてだけ使う形です。外部から叩く起動口の作り方はGitHub Actionsの手動実行(workflow_dispatch)|inputsの型定義とCLI・APIからの起動にまとめています。Google Cloudを併用しているならフルマネージドのcronであるCloud Schedulerが候補で、仕組みとリトライ設定はCloud Schedulerの解説記事にまとめています。
この構成では起動用の認証情報をどこに置くかが論点になります。GitHub側のシークレットと外部側の資格情報が二重管理になりやすいため、値の置き場所の原則はenv・vars・secretsの使い分けに合わせて決めておくと管理が破綻しません。
定期実行が動かないときに疑う既定ブランチ配置と60日停止の条件
「昨日まで動いていたのに今日は走っていない」という報告の原因は、多くの場合この章の3つに収まります。順に確認すれば切り分けが済みます。
ワークフローファイルが既定ブランチに無い場合に発火しない仕様
定期実行は既定ブランチの最新コミットに対して走り、ワークフローファイルが既定ブランチに存在しなければそもそも起動しません。機能ブランチでscheduleを書いて動作確認しようとしても、マージするまで1回も走らないということです。テスト時はworkflow_dispatchを併記して手動起動で中身を確かめ、cronの時刻指定そのものはマージ後に実際の起動ログで検証する手順が確実でしょう。既定ブランチを切り替えた場合も、切り替え後のブランチにファイルが無ければ止まります。
パブリックリポジトリが60日の無活動で自動停止する条件と再開方法
パブリックリポジトリでは、60日間リポジトリの活動が無いと定期ワークフローが自動的に無効化されます。コミットもIssueも無い状態が2か月続く社外公開リポジトリ、たとえば公開しているサンプルやドキュメントサイトの更新チェックなどが該当しやすい対象です。無効化されたワークフローはリポジトリのActions画面から再有効化できます。
停止を避けたいだけであれば、無意味なコミットを自動生成するより、そもそもプライベートリポジトリへ置くか、外部スケジューラからのworkflow_dispatch起動へ切り替えるほうが筋が通ります。
通知先とactorがcronを最後に変更した人へ紐づく仕組みと影響
定期ワークフローの実行通知は、ワークフローファイルのcron構文を最後に変更した利用者へ送られます。無効化された定期ワークフローは、書き込み権限を持つ利用者がcronの記述を変更するコミットを行うと再有効化され、その利用者が以後のactorになります。
この紐づけは組織運用で効いてきます。Enterprise Managed Usersの環境では、actorとなっている利用者のアカウントがIdP側で解除されると定期ワークフローは走りません。担当者の退職や異動で夜間バッチが静かに止まる事故はここから生まれるため、失敗通知をチーム宛のチャットへ流す仕組みを別途持たせておくのが安全です。通知を書き込むジョブに何の権限が要るかはGitHub Actionsのpermissions|GITHUB_TOKENの既定権限と最小権限の設計で確かめられます。
受託開発で定期実行に向く処理と専用スケジューラへ分ける判断基準
ここまでの仕様を踏まえると、scheduleに載せてよい処理の条件はかなりはっきりします。私たちが受託開発の運用設計で採否を判断するときの基準を、条件付きで言い切ります。
遅延を吸収できる冪等なバッチを定期実行に載せてよい条件と設計
採用してよいのは、次の3条件をすべて満たす処理です。第一に、数十分の遅延が業務影響を持たないこと。第二に、同じ入力で2回走っても結果が壊れない冪等性があること。第三に、1回スキップされても次回の実行で取り戻せること。
この条件に収まる典型が、依存ライブラリの更新確認、リンク切れやTLS証明書の期限チェック、ステージング環境の夜間クリーンアップ、日次のレポート生成といった開発者向けの定型作業です。これらは実行環境がすでにリポジトリの中にあり、外部基盤を足さずに済む点で費用対効果が高くなります。
締め切りのある業務処理を専用スケジューラへ寄せる判断基準と移行先
見送るべきなのは、時刻そのものが要件になっている処理です。締め日の請求データ確定、取引先へのファイル送信、営業時間開始に間に合わせる必要のあるデータ同期などは、遅延と欠落を許容できません。実行時間が数時間に及ぶ処理や、専用ネットワークからしか到達できない社内システムを叩く処理も同様に外れます。
これらは専用のスケジューラとジョブ基盤へ寄せ、GitHub Actionsはコードの検証と配信に専念させる分担が扱いやすくなります。CI/CD全体をどう組み立てるかという前提整理はCI/CDの仕組みと導入判断の解説を参照してください。
定期実行を採用してよい条件と見送るべき場面を分ける判断基準の整理
判断の順序をまとめると、まず「遅れても業務が困らないか」を問い、困るなら定期実行の対象外とします。困らない場合は次に「2回走って壊れないか」を確認します。壊れるなら排他制御か冪等化を先に入れてください。GitHub Actions内で実行の重なりだけを止めるなら、GitHub Actionsのconcurrency|groupの設計とcancel-in-progress・queueの選び方のグループ指定が最短の手当てです。最後に「止まったとき誰に届くか」を決め、通知の宛先を個人ではなくチームへ向けます。この3問を通過した処理だけをcronに載せる運用で、夜間バッチの事故は大きく減らせます。
すでに動いている定期ジョブの棚卸しや、遅延前提の設計への作り替え、運用そのものの内製化を進めたい場合は、保守運用・内製化支援でCI/CDの運用引き取りから体制づくりまで対応しています。既存ワークフローの読み解きと停止条件の洗い出しから着手できます。
よくある質問
cronで指定した時刻ちょうどに実行されないのはなぜですか?
仕様どおりの挙動です。scheduleイベントは実行が集中する時間帯に遅延することがあり、毎時の開始時刻がその代表です。負荷が高いとキュー中のジョブが破棄される場合もあります。実行時刻を毎時00分から別の分へずらすのが公式の推奨で、それでも定刻が必要なら外部スケジューラからの起動へ切り替えてください。
日本時間で指定するにはどう書けばよいですか?
2026年8月時点では2通りあります。cronと並べてtimezoneにAsia/Tokyoを書く方法と、UTC基準で日本時間から9時間を引いて書く方法です。前者は2026年3月の更新で入った書き方で、時差の暗算が不要になります。既存資産の書き換えを伴わない新規ジョブでは前者を推奨します。
1分ごとに実行することはできますか?
できません。定期実行の最短間隔は5分に1回です。*/1 * * * * と書いても毎分は起動しません。分単位の監視や即応が必要な用途では、常駐プロセスやマネージドな監視サービスを選ぶほうが要件に合います。
機能ブランチに置いたcronが動かないのですが仕様ですか?
仕様です。定期実行は既定ブランチの最新コミットに対して走り、ワークフローファイルが既定ブランチに無ければ起動しません。マージ前に動作を確かめたいときはworkflow_dispatchを併記し、手動起動で処理内容だけ検証してください。
しばらく放置したら定期実行が止まっていました。原因は何ですか?
パブリックリポジトリなら、60日間リポジトリの活動が無かったことによる自動無効化が有力です。Actions画面から再有効化できます。加えて、通知やactorがcronを最後に変更した利用者へ紐づくため、その利用者のアカウントが組織の管理下で解除されている場合も走らなくなります。
関連記事
- GitHub Actionsのトリガー(on)|イベント選定とbranches・pathsフィルタの設計:push・pull_request側の発火条件をまとめて設計したい場合の参照先です。
- GitHub Actionsとは?できること・使い方とCI/CD自動化の解説記事:ワークフローの基本構造と全体像から確認できます。
- GitHub Actionsの料金|2026年改定後の分単価・無料枠とコスト削減の判断基準:実行頻度を決める前の費用見積もりに使えます。
- GitHub Actionsの環境変数|env・vars・secretsの使い分けと受け渡し:定期ジョブが使う認証情報の置き場所を決められます。
- Cloud Schedulerとは?GCPのフルマネージドcronの仕組みとCloud Tasksとの違い:定刻精度が要る処理を外部へ寄せるときの選択肢です。
- CI/CDとは?仕組み・パイプライン・導入すべき企業の判断基準を解説:定期ジョブを含む全体設計の前提を整理できます。