はじめに
「毎日決まった時間にデータを取得したい」
「毎月1日にレポートを自動生成したい」
処理そのものは書けても、それをどこで動かすかで迷うことはないでしょうか。
この記事では、定期実行の代表的な選択肢を比較し、どういうケースでどれを選ぶべきかを整理します。
選択肢の一覧
| 手段 | 費用 | 環境構築 | 向いている処理 |
|---|---|---|---|
| GAS(Google Apps Script) | 無料 | 不要 | Googleサービス連携 |
| cron(レンタルサーバー) | サーバー代のみ | 少し必要 | PHP/Python、DB操作 |
| GitHub Actions | 無料枠あり | 中程度 | コード管理と一体の処理 |
| クラウド関数(Lambda等) | 従量課金 | 必要 | 大規模・高頻度 |
① GAS(Google Apps Script)
向いているケース
- スプレッドシート・Gmail・カレンダーなどGoogleサービスを操作する
- 環境構築なしですぐ始めたい
- 処理が数分以内で終わる
メリット
- 完全無料、サーバー不要
- Googleアカウントだけで始められる
- Googleサービスへのアクセスが認証済みで簡単
制約
| 項目 | 無料アカウントの上限 |
|---|---|
| 1回の実行時間 | 6分 |
| 1日の総実行時間 | 90分 |
| メール送信 | 100通/日 |
| トリガー数 | 20個/スクリプト |
注意点:実行時刻がずれる
GASの時間主導型トリガーは「9時ちょうど」ではなく「9時〜10時の間」という幅で実行されます。分単位の正確さが必要な処理には向きません。
設定例
function dailyTask() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// 処理内容
MailApp.sendEmail('you@example.com', '日次レポート', '処理が完了しました');
}
トリガー設定:左メニュー「トリガー」→「+トリガーを追加」→ 時間主導型を選択。
② cron(レンタルサーバー・VPS)
向いているケース
- PHPやPythonのスクリプトを動かしたい
- データベースに直接アクセスする
- 実行時刻を正確にコントロールしたい
- 6分以上かかる処理がある
メリット
- 実行時刻が正確(指定した分に実行される)
- 実行時間の制限が緩い(サーバー設定次第)
- 既存のWebサーバーをそのまま使える
cron の書き方
# 分 時 日 月 曜日 コマンド
# 毎日 朝6時に実行
0 6 * * * /usr/bin/php /home/user/scripts/daily.php
# 毎週月曜の9時30分
30 9 * * 1 /usr/bin/python3 /home/user/scripts/weekly.py
# 平日のみ、1時間ごと
0 * * * 1-5 /usr/bin/php /home/user/scripts/hourly.php
# 毎月1日の0時
0 0 1 * * /usr/bin/php /home/user/scripts/monthly.php
実務での必須ポイント
1. ログを必ず残す
0 6 * * * /usr/bin/php /home/user/daily.php >> /home/user/logs/daily.log 2>&1
2>&1 を付けるとエラー出力もログに記録されます。これがないと「動かなかったけど原因が分からない」状態になります。
2. 絶対パスで書く
cronの実行環境はログイン時と異なり、PATHが限定されています。コマンドもファイルもフルパスで指定します。
# ❌ 動かないことがある
0 6 * * * php daily.php
# ✅ 確実
0 6 * * * /usr/bin/php /home/user/scripts/daily.php
3. タイムゾーンを確認する
サーバーのタイムゾーンが日本時間とは限りません。
# サーバーの現在時刻を確認
date
海外サーバーの場合、スクリプト側でタイムゾーンを明示するのが安全です。
date_default_timezone_set('Asia/Tokyo');
4. 多重起動を防ぐ
処理が長引いて次のcronが重なると、二重実行で事故ります。
# flockでロックをかける
0 * * * * /usr/bin/flock -n /tmp/mytask.lock /usr/bin/php /home/user/task.php
③ GitHub Actions
向いているケース
- コードをGitHubで管理している
- Python/Node.jsなどのライブラリを使う処理
- サーバーを持ちたくない
メリット
- サーバー不要でスケジュール実行できる
- コードと実行環境が同じ場所で管理できる
- パブリックリポジトリなら実質無料
設定例
.github/workflows/scheduled.yml を作成します。
name: Daily Task
on:
schedule:
# cron形式(UTC基準!)
- cron: '0 21 * * *' # UTC 21:00 = JST 6:00
workflow_dispatch: # 手動実行も可能にする
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run script
env:
API_KEY: ${{ secrets.API_KEY }}
run: python main.py
注意点
- 時刻はUTC基準。JSTにするには9時間引いて指定します
- スケジュール実行は遅延することがある(混雑時は数十分ずれることも)
- プライベートリポジトリは無料枠(月2,000分)を消費します
- 60日間コミットがないと自動的に無効化されます
選び方のフローチャート
Googleサービス(スプレッドシート/Gmail等)を操作する?
├ YES → GAS
└ NO
↓
実行時刻の正確さが重要? or 6分以上かかる?
├ YES → cron(レンタルサーバー/VPS)
└ NO
↓
すでにGitHubでコード管理している?
├ YES → GitHub Actions
└ NO → cron または GAS
併用も現実的
実務では組み合わせることも多いです。
例:ECサイトの日次レポート
① cron(サーバー)
→ 深夜2時にDBから前日データを集計してCSV出力
② GAS
→ 朝6時にそのCSVをスプレッドシートに取り込み、
Looker Studioのダッシュボードを最新化
③ GAS
→ 朝8時に関係者へサマリーをメール送信
「重い処理はサーバー、Google連携はGAS」という分担が合理的です。
共通して大事なこと
手段に関わらず、定期実行を運用するなら以下は必須です。
① 失敗に気づける仕組みを作る
一番怖いのは「止まっていることに誰も気づかない」状態です。
// 処理の最後に成功通知を送る(またはSlack/LINEに通知)
if ($success) {
// 正常終了をログに記録
} else {
mail('you@example.com', '【エラー】日次処理が失敗しました', $errorMessage);
}
② 冪等性を意識する
同じ処理を2回実行しても結果が壊れない設計にします。
-- ❌ 二重実行で重複が発生
INSERT INTO daily_summary (date, total) VALUES ('2026-04-01', 50000);
-- ✅ 何度実行しても同じ結果
INSERT INTO daily_summary (date, total) VALUES ('2026-04-01', 50000)
ON DUPLICATE KEY UPDATE total = VALUES(total);
③ 手動実行できるようにしておく
「失敗したので今すぐ再実行したい」というケースは必ず起きます。cronならコマンドを直接叩ける状態に、GitHub Actionsなら workflow_dispatch を入れておきます。
まとめ
| 状況 | おすすめ |
|---|---|
| Googleサービス操作が中心 | GAS |
| DBアクセス・重い処理・正確な時刻 | cron |
| GitHubでコード管理している | GitHub Actions |
そして手段に関わらず、ログ・エラー通知・冪等性・手動実行の4点は必ず用意しておくこと。これがないと、動いているのか止まっているのか分からない「見えない自動化」になってしまいます。
業務の自動化・定期処理のご相談
「どの方法で動かすべきか相談したい」「既存の自動化が不安定で困っている」などのご相談を受け付けています。