予約通知エラーの発生:Cloud Tasksで数ヶ月先の予約通知を送るための設計手法と注意点
Meg
Meg
2026-08-27
Google Cloud Tasksには「30日先まで」という予約制限があり、数ヶ月先の通知予約を直接登録すると送信漏れが発生します。本記事では、FirestoreとCloud Schedulerを組み合わせ、29日を境界値としてタスクを管理する堅牢なアーキテクチャを解説します。コストを抑えつつ、長期予約を確実に実行するためのベストプラクティスと実装のポイントを紹介します。

プッシュ通知やメール送信などで「指定日時に処理を実行したい」場合、Google Cloud Tasks は非常に便利なサービスです。 タスクごとに scheduleTime を指定できるため、「◯月◯日 11:00 にこの通知を送る」といった予約処理を簡単に実装できます。 しかし、Cloud Tasks を使った長期予約には注意すべきシステム制限があります。

Cloud Tasks の制限と発生した問題

Google Cloud の公式ドキュメントでは、Cloud Tasks の制約として以下が定義されています。

  • タスクの最大保持期間: 31日
  • タスクの最大予約可能期間: 現在日時から30日先まで (参考: Cloud Tasks quotas and limits)

つまり、数ヶ月先の予定を Cloud Tasks に直接登録しようとすると、登録時にエラーになるか、仮に登録できても送信予定日になる前にタスクが期限切れで自動削除されてしまいます。

送信されなかった原因の分析

実際に発生した未送信通知の条件を確認したところ、以下のような状態でした。

  • ケースA: 作成日から送信予定日まで 約45日
  • ケースB: 作成日から送信予定日まで 約76日

どちらも作成日から送信予定日まで31日を超えていました。 一方、作成から送信予定までが数分〜数時間程度の短期予約タスクは正常に実行されていました。

このことから、送信ロジックや外部配信サービスの問題ではなく、Cloud Tasks に長期間先のタスクを直接登録していたことが直接の原因であると判明しました。

どうしても長期予約を扱いたい場合

この場合は、Cloud Tasks に直接登録せず、一度 Firestore などのデータベース で予約情報を管理します。


[CMS / 管理画面]
│
├─ 送信予定が【29日より先】 ───> Firestore に保存のみ
│                                   │
│                                   ▼ (1日1回のバッチチェック)
│                               [Cloud Scheduler]
│                                   │ (29日以内に入ったデータをピックアップ)
│                                   ▼
└─ 送信予定が【29日以内】 ───────> [Cloud Tasks] へ登録 
│
▼ (指定日時に呼び出し)
[Cloud Functions / Cloud Run] (通知送信処理)

なぜ「30日」ではなく「29日」で分岐・運用するのか?

Cloud Tasks の上限は「30日先まで」ですが、API呼び出し時のネットワーク遅延やサーバ間のミリ秒単位の時刻ズレにより、ぴったり30日を指定すると エラーになるリスクがあります。そのため、システム判定の境界値は安全策として「29日(または29.5日)」に設定する のが実務上のベストプラクスティスです。

全体の処理フロー

  1. 予約作成時の分岐:
    • 29日より先の長期予約: Firestore にのみ保存
    • 29日以内の短期・直前予約: Firestore に保存すると同時に、その場で直接 Cloud Tasks へも登録。※バッチ処理の実行を待たずに即時スケジューリングするため。
  2. 定期チェック(1日1回):
    • Cloud Scheduler が1日1回(夜間など)バッチを起動。
    • Firestore から「送信予定日が29日以内に入った未登録データ」をクエリで抽出して Cloud Tasks に登録し、ステータスを enqueued に更新。
  3. タスク実行:
    • 指定日時になったら Cloud Tasks から送信用エンドポイント(Cloud Functions / Cloud Run 等)を呼び出して処理を実行。

コスト面での影響

「定期的に Scheduler を回して DB をチェックする」と聞くとコストが気になるかもしれませんが、この構成なら月額数十円〜ほぼ無料に収まります。

  • Cloud Scheduler: 1日1回の実行であれば月間30回程度の呼び出しです。無料枠(月3ジョブまで無料)に余裕で収まります。
  • Firestore: statussendDate複合インデックスを作成しておくことで、条件に該当するデータのみピンポイントで読み取れます(対象外の数万件の長期データは読み取りカウントされません)。1日1回チェック+10,000件/月 程度の運用であれば無料枠(1日5万読み取り)に収まるため、コストは実質数円程度です。
  • Cloud Tasks: 最初の 100 万オペレーション/月 は無料枠の対象です。

まとめ

Cloud Tasks は「数分後」「数時間後」「数日後」のような 短期予約・非同期実行 には非常に強力ですが、数ヶ月先の長期予約を直接保持させる用途には向いていません。

  • 長期予約(29日超): Firestore などの DB で状態管理
  • 短期予約(29日以内): 作成時または 1日1回の Cloud Scheduler 経由で Cloud Tasks に登録
  • 境界値の考慮: 30日ギリギリではなく「29日」を判定基準にしてエラーを防ぐ

この役割分担と境界値設計を行うことで、コストを最小限に抑えつつ、送信漏れのない堅牢なシステムを構築できます。