個人開発のAI定期ジョブはどこに置くべきか?ノートPCのlaunchdとGitHub Actions cronを比べる
GitHub Actionsの公式ドキュメントには、cron(定時実行の設定)で動くscheduleイベントは、高負荷の時間帯に遅延することがあり、負荷が高ければキューに入ったジョブが破棄される場合もある、という趣旨の記載がある。特に毎時0分付近が混みやすいとされている。一方、macOS標準のジョブ管理の仕組みであるlaunchd(ランチディー)は、Macがスリープ中や電源オフの間は予定時刻に処理を実行できない。
毎朝のニュース要約や週次レポートの自動生成など、LLM(大規模言語モデル。ChatGPTのような文章生成AIの中核技術)を使った定期ジョブは、個人でも珍しくなくなった。実行場所の選択肢は、手元のノートPCで動かすlaunchdと、クラウド上で動かすGitHub Actionsの2つが代表的と言える。
ExcelのマクロやWindowsのタスクスケジューラでPC作業を自動化した経験があれば、「PCが閉じていたら動かない」という落とし穴はなじみ深いはずだ。本稿では両者を同じ条件で比べるための測定の設計と、公式仕様から見える傾向を整理する。
本稿における数値の扱い 本稿には実測の数値(遅延が何分、成功率が何%など)は載せていない。結果は環境や時期で大きく変わるため、記載は公式ドキュメントに書かれた挙動と、一般に知られた傾向にとどめた。後半では、読者が自分の環境で同じ測定をするための手順と記録用スクリプトを示す。
launchdとGitHub Actions cronは何がどう違うのか?
動く場所と、左右される条件
launchdは、自分のPC上で動く。したがって次の状態に結果が左右される。
- PCの電源が入っているか
- スリープ中か、蓋が閉じているか
- ネットワークにつながっているか(LLMのAPI呼び出しには通信が必須)
- ログインしているか(ユーザー単位の設定である LaunchAgents は、ログイン中に動くのが基本)
GitHub Actionsは、GitHubが用意するクラウド上の仮想マシン(コンピューター内に作られた仮想のパソコン)で動く。手元のPCの状態には依存しない。その代わり、混雑時の遅延が公式に許容されている。GitHub側が時刻を保証していない点は、仕様として押さえておく必要がある。
設定・秘密情報・ログの違い
| 項目 | launchd(ノートPC) | GitHub Actions(cron) |
|---|---|---|
| 設定ファイル形式 | plist(プロパティリスト。XML形式の設定ファイル) | YAML(インデントで階層を表すテキスト形式) |
| 設定の置き場所 | ~/Library/LaunchAgents/ など |
リポジトリ内の .github/workflows/ |
| 時刻の基準 | PCのローカル時刻 | UTC(協定世界時。日本時間はUTC+9) |
| 最短の間隔 | 秒単位で指定可能 | 5分(公式の下限) |
| シークレット(APIキーなどの秘密情報) | 環境変数、キーチェーン(Macのパスワード保管機能)など自前で管理 | Secrets機能で暗号化して保管 |
| ログの残り方 | 標準出力・標準エラーの出力先ファイルを自分で指定 | 実行ごとにWeb画面で確認でき、一定期間保持される |
| 失敗時の通知 | 標準では何も来ない(自前の仕組みが必要) | 設定により失敗が通知される |
| スリープ・電源オフ時 | 動かない、または復帰後にまとめて実行 | 影響なし |
時刻の基準には注意が必要だ。GitHub Actionsのcronは日本時間ではなくUTCで書くため、毎朝6時台に動かしたい場合は前日21時台(UTC)で指定する。この変換ミスは、初心者が最初につまずきやすい点と見られる。
どのように測定したのか?
測定の設計
比較の前提は「同じジョブを、同じ時刻に、両環境へ登録する」ことだ。ジョブの例としては、次のような処理が考えられる。
- LLMのAPIを呼び出す
- 数百〜数千字のテキストを要約させる
- 結果をファイルに書き出す
処理内容を揃えることで、差が実行環境に由来するのか、ジョブ側の問題なのかを切り分けられる。
計測項目
| 計測項目 | 何を見るか | 記録の方法 |
|---|---|---|
| 開始時刻のずれ | 予定時刻と実際の開始時刻の差 | 開始時に現在時刻を記録し、予定時刻との差を計算 |
| 実行成功率 | 実行されたもののうち正常終了した割合 | 終了コード(0なら成功)を記録 |
| 所要時間 | 開始から終了までの時間 | 開始・終了時刻の差 |
| 取りこぼし回数 | 予定されたのに実行記録がない回数 | 予定日ごとの記録の有無を集計 |
| 復旧にかかった手間 | 失敗に気づき、直し、再実行するまでの作業 | 気づくまでの時間と作業内容をメモ |
「開始時刻のずれ」と「取りこぼし」は別物として分けて記録する。遅れて動いたのか、まったく動かなかったのかで、意味が大きく変わるためだ。
条件の明示
測定結果を読むには条件の明示が欠かせない。最低限、次の項目は記録したい。
- 測定期間とサンプル数(予定回数)
- ノートPCの使い方(持ち歩き、蓋閉じ、Wi-Fi切り替えの頻度、電源アダプタの有無)
- macOSのバージョンと省電力設定
- GitHub側のリポジトリ種別(公開・非公開)と、cronに指定した時刻
結果の限界
この種の測定には次の限界がある。
- ノートPCの使い方は人によって違い、結果をそのまま一般化できない
- GitHub Actionsの混雑は時間帯や時期で変わるため、短期間の測定では偏りが出る
- サンプル数が数十回程度では、まれな障害は捉えにくい
記録用の最小スクリプト例
ジョブの先頭と末尾に、次のような記録処理を入れる方法がある(シェルスクリプトの例)。
#!/bin/bash
# 予定時刻(UTC)を引数で受け取る 例: 2025-01-01T21:17:00Z
SCHEDULED="$1"
ENV_NAME="$2" # "launchd" か "actions"
START=$(date -u +%FT%TZ)
python summarize.py # 実際のAIジョブ
CODE=$?
END=$(date -u +%FT%TZ)
echo "$ENV_NAME,$SCHEDULED,$START,$END,$CODE" >> run_log.csv
run_log.csv をスプレッドシートで開けば、開始のずれや成功率は関数やピボットテーブルで集計できる。GitHub Actions側では、このCSVをArtifact(実行結果の保存機能)として保存するか、リポジトリにコミットすれば残せる。
実行時刻のずれや取りこぼしはどの程度起きるのか?
以下は仕様と一般的な傾向に基づく整理であり、具体的な数値は前節の方法で各自が測定する想定だ。
launchdで起きうること
launchdの StartCalendarInterval(カレンダー指定の実行)には、スリープに関する次の仕様がある。
- スリープ中に予定時刻を過ぎた場合: 復帰後に実行される。予定時刻に対しては大きな遅れになる。
- スリープ中に複数回分の予定が重なった場合: 1回にまとめられる(取りこぼしに見える)。
- 電源オフの場合: 実行されない。
- 蓋を閉じた場合: 外部ディスプレイと電源を接続するクラムシェルモードなどの例外を除き、Macはスリープに入るため、予定時刻に実行されないケースがあると見られる。
回避策としては、pmset(電源管理のコマンド)による定時の起動・復帰設定や、caffeinate(スリープ抑止のコマンド)の併用がある。ただし、持ち歩くノートPCで常に確実に動かすのは難しい。
GitHub Actionsで起きうること
GitHub Actionsでは、混雑しやすい時刻に数分から数十分の遅延が出る傾向が知られている。特に毎時0分や30分のようなキリのよい時刻に集中しやすい。有効とされる工夫は単純で、時刻をずらすことだ。
on:
schedule:
- cron: "17 21 * * *" # UTC 21:17 = 日本時間 6:17
毎時0分を避け、「17分」のような中途半端な時刻を選ぶだけで、混雑の影響を受けにくくなる可能性が高い。
もう1つの注意点として、公開リポジトリでは、一定期間リポジトリの活動がないとscheduleのワークフローが自動で無効化される仕様がある。長期間動かしっぱなしにする場合は、この仕様の確認が必要だ。
「遅延」と「取りこぼし」を分けて評価する
| 観点 | launchd(ノートPC) | GitHub Actions |
|---|---|---|
| 遅延の主因 | スリープ・蓋閉じ・電源状態 | クラウド側の混雑 |
| 遅延の大きさ | 数時間規模になりうる(復帰まで) | 数分〜数十分規模と言われる |
| 取りこぼしの主因 | 電源オフ、予定のまとめ込み | 高負荷時のキュー破棄(まれ) |
| 対策 | 電源設定、常時給電 | 時刻をずらす、失敗通知を設定 |
評価の分かれ目は、「厳密な時刻」と「確実な実行」のどちらが重要かにある。
- 「朝8時に必ず届いてほしい」ジョブでは、遅延の小さい環境が望ましい。
- 「1日1回、いつかは必ず実行されてほしい」ジョブでは、取りこぼしの少ない環境が望ましい。
GitHub Actionsは後者に強く、launchdはPCの使い方次第で、どちらにも転びうると見られる。
コストと運用の手間はどちらが小さいのか?
金銭的なコスト
GitHub Actions:
- 公開リポジトリでは標準ランナー(標準の仮想マシン)の利用が無料とされている。
- プライベートリポジトリでは、プランごとに月間の実行分数の無料枠があり、超過すると課金される。
- 実行分数はOSで倍率が異なり、Linuxが最も安く、macOSは高い倍率で計算される。
具体的な枠や倍率は変更されうるため、最新の公式料金表の確認が必要だ。数十秒で終わるAI要約ジョブを1日1回動かす程度なら、無料枠に収まる場合が多いと見られる。
launchd:
- 追加の利用料はかからない。
- ただし、PCを動かし続けるための電力、PCを起こしておく運用上の制約といった目に見えにくいコストがある。
運用の手間
launchdの保守負担として挙げられるのは次の点だ。
- OSアップデート後に設定が効かなくなる、権限(フルディスクアクセスなど)の再許可が必要になる
- plistの記述ミスが分かりにくい(書式の誤りで静かに動かない)
- ジョブの登録・解除に
launchctlコマンドの知識が必要
GitHub Actionsの保守負担は次の点だ。
- 使っているアクションのバージョン更新への追随
- 仕様変更(無料枠、非推奨機能)の確認
失敗時の見通しやすさ
| 項目 | launchd | GitHub Actions |
|---|---|---|
| 失敗の通知 | 標準ではなし。メールやチャット通知を自作 | 失敗通知を設定可能 |
| リトライ(再試行) | スクリプト内で自前実装 | 手動の再実行ボタン、または処理内で実装 |
| ログ確認 | ログファイルを開く | Web画面で実行ごとに確認 |
運用の見通しやすさでは、GitHub Actionsに利点があると言える。特に「失敗したことに気づける」点は、個人の自動化を長続きさせるうえで大きい。launchdでは、失敗しても何も起きないため、数日後に気づく例が起こりやすい。
セキュリティやデータの扱いに違いはあるのか?
launchdの場合
APIキーはローカルの環境変数やキーチェーンに置くことになる。注意点は次のとおり。
- PC紛失や盗難のリスクを考慮する必要がある(ディスク暗号化のFileVaultを有効にするのが基本)
- plistに直接キーを書くと、ファイルとして平文(暗号化されていない文字列)で残る
- キーチェーンを使えば、平文での保存を避けられる
GitHub Actionsの場合
APIキーはSecrets(暗号化された秘密情報の保管機能)で管理できる。ただし、次の点には注意が必要だ。
- リポジトリの設定: リポジトリの公開範囲や共同作業者の権限を誤ると、扱いが甘くなる。
- 第三者アクション: 他者が公開した部品(アクション)を使うと、その中身が秘密情報にアクセスしうる。信頼できるものに限り、バージョンの固定(コミットSHAによる指定など)が推奨されている。
- ログへの出力: Secretsはログ上でマスクされるが、加工した文字列などは漏れる可能性がある。
- 権限の最小化: ワークフローに与える権限(
permissions)を必要最小限にする。
データの置き場所が判断の分かれ目
社内資料、顧客情報、ローカルに保存した個人ファイルを扱うジョブでは、そのデータをクラウドに置いてよいかが最初の判断基準になる。会社の情報管理規程でクラウド上での処理が認められていなければ、選択肢はlaunchd側に限られる。なお、LLMのAPIにテキストを送る時点で、データは外部サービスに渡る。この点は、どちらの環境でも共通だ。
結局、どんなジョブをどちらに置くべきか?
ジョブの種類による目安
| ジョブの種類 | 向いている置き場所 |
|---|---|
| ローカルファイル(ダウンロードフォルダ、Excelファイルなど)を処理する | launchd |
| ログイン済みのブラウザ操作に依存する | launchd |
| 公開ニュースや公開APIのデータを要約する | GitHub Actions |
| 週次・月次の定期レポート | GitHub Actions |
| 試作・デバッグ段階のジョブ | launchd(手元で試しやすい) |
併用という選択肢
「試作とデバッグはローカル、本番はクラウド」という使い分けも成り立つ。手元で動作を確認してからYAMLに移せば、設定の試行錯誤をクラウド側で繰り返さずに済む。
判断のためのチェックリスト(4軸)
1. 時刻の厳密さ
- 数十分の遅れは許容できる → GitHub Actionsで問題になりにくい
- 指定時刻ちょうどが必要 → どちらも保証はない。設計の見直しが必要
2. PCへの依存
- PCが閉じていても動いてほしい → GitHub Actions
- ローカルのファイルやアプリが必要 → launchd
3. データの機密性
- クラウドに置けないデータを扱う → launchd
- 公開データのみ → どちらでも可
4. 保守の手間
- 失敗の通知とログの確認を手軽にしたい → GitHub Actions
- 追加費用を避けたい、手元で完結させたい → launchd
左側(クラウド寄り)に多くチェックが付けばGitHub Actions、右側(ローカル寄り)に多ければlaunchdが候補になると見られる。
まとめ:置き場所は何を基準に決めればよいのか?
整理すると、次のように言える。
- 確実性では、PCの状態に左右されないGitHub Actions(クラウド)に利点がある。
- 柔軟性とローカル資源へのアクセスでは、launchdに利点がある。
- 時刻の厳密さは、どちらの環境でも保証されていない。許容する遅延の大きさをジョブごとに決めておく必要がある。
個人開発の自動化を長続きさせる条件は、「どちらが優れているか」を一律に決めることではなく、ジョブごとに要件を見極めて置き場所を選ぶことと言える。特に、失敗に気づける仕組みを最初に用意しておくことが、運用を続けるうえで効くと見られる。
今後の検討課題として、次の選択肢との比較が挙げられる。
- 常時稼働の小型サーバー(Raspberry Piなど)
- クラウド関数(AWS LambdaやGoogle Cloud Functionsのように、必要なときだけ処理を動かすサービス)
これらは、ノートPCの不安定さとクラウドの時刻の揺らぎの、中間に位置する選択肢と見られる。
今日からできる準備
- 動かしたいジョブを1つ決め、上のチ