AI活用

Cloudflare Workers Cron Triggersの上限は無料5本・有料250本。公式ドキュメントで見る逃げ方4つ

Cloudflare Workers Cron Triggersの上限は無料5本・有料250本。公式ドキュメントで見る逃げ方4つ

おはようございます。まさきんです。

Cloudflare Workers の Cron Triggers は、公式ドキュメントで無料プランの上限が5本と決まっています。僕も家の自動化を無料枠でやりくりしていて、先日この上限に当たりました。そのときの逃げ方を、公式の情報と合わせて整理しておこうと思います。

※記事公開時点の情報です。最新の条件は公式サイトでご確認ください。

POINT
  • Workers Freeでは、Cron Triggersはアカウント全体で5本までです
  • 近い用途の時刻は1本の式にまとめ、ハンドラ内で振り分けられます
  • 起動役だけを自宅PCなどに出せば、処理はWorkerに残せます
  • 外から叩くなら、秘密トークンでの認証とタイムアウトの設定が要ります
  • それでも足りなければ、有料プランの250本に移るのが素直です

上限に当たった経緯

健康データを通知するWorkerに、Cron Triggersを3本足してデプロイしました。すると、スケジュールの設定だけが失敗しました。エラーコードは10072で、Workers Freeのアカウント上限に当たっていたのが原因です。

コード自体のデプロイは通っていました。なので、一見すると成功したように見えるのが少しやっかいです。ログを見ずに放っておくと「なぜか動かない」になっていたかもしれません。

無料枠の上限は5本

公式のLimitsページでは、Cron Triggersの本数はアカウント単位で決まっています。Worker 1本ごとではない点が大事です。

項目Workers FreeWorkers Paid
Cron Triggersの本数(アカウント全体)5250
Cron起動時のCPU時間10ms30秒(1時間未満の間隔)/15分(1時間以上の間隔)
HTTP起動時のCPU時間10ms最大5分(既定30秒)
リクエスト数1日10万まで(UTC 0時にリセット)月1,000万まで料金に込み

家の自動化は、小さなWorkerを用途ごとに分けがちです。1本のWorkerに2〜3個のスケジュールを持たせると、5本はすぐに埋まります。僕の場合も、気づいたら満杯でした。

Cron Triggersの基本をおさらい

逃げ方を考える前に、仕様を確認しておきます。ここを押さえると、打てる手がいろいろ見えてきます。

注意したいのはUTCの点です。日本時間はUTCより9時間進んでいます。朝6時30分に動かしたいなら、UTCでは前日の21時30分と書くことになります。

controller.cronには、設定した式の文字列がそのまま入ります。公式では、スペースも含めて一字一句一致させる必要があると書かれています。古い書き方のevent.cronで書いたコードも、考え方は同じですね。

逃げ方は大きく4つ

僕が検討した選択肢を、先に表で並べておきます。

逃げ方枠の節約長所短所
(1) 複数の時刻を1本の式にまとめる大追加の仕組みが要らない時刻の振り分けをコードで持つ
(2) 起動役だけ外に出す大頻度を自由に増やせる外の起動役が止まると動かない
(3) ディスパッチャWorkerに集約する大Cloudflareの中で完結する1か所の不具合が全部に響く
(4) 有料プランへ移る根本解決上限が250本に広がる月額5ドルから費用がかかる

(1)から試して、足りなければ(2)か(3)に進む。最後に(4)を考える。この順番が、無料枠でやりくりするなら素直かもしれません。

逃げ方1:時刻を1本の式にまとめる

一番手軽なのがこれです。朝と昼に別々の式を書いていたとします。同じWorkerの中なら、時の欄をカンマでつなげば1本になります。

僕は朝と昼の2本を、次の1本にまとめて再デプロイしました。

[triggers]
crons = ["30 3,21 * * *"]

UTCの21時30分は、日本時間の朝6時30分です。UTCの3時30分は、日本時間の昼12時30分です。これで枠が1本空きました。

式が1本になると、controller.cronではどちらの時刻か区別できません。なので、起動予定の時刻からUTCの「時」を取り出して振り分けます。

export default {
  async scheduled(controller, env, ctx) {
    const hourUtc = new Date(controller.scheduledTime).getUTCHours();
    if (hourUtc === 21) {
      await sendMorning(env); // 日本時間 6:30
    } else if (hourUtc === 3) {
      await sendNoon(env); // 日本時間 12:30
    }
  },
};

scheduledTimeは、起動が予定されていた時刻です。実際に動いた時刻より、こちらで判定するほうが安定すると思います。

ただ、まとめられるのは「分」が同じ時刻に限られます。6時30分と12時15分のように分がずれると、1本の式では表せません。そのときは、分をそろえてよいか一度考えてみるのがよさそうです。

まとめても満杯なら

僕の場合、朝昼をまとめても5本は満杯のままでした。新しい処理を足す余地がありません。

そこで、残りのCronを見直しました。位置情報の同期が1本、家のサイネージ更新が2本です。この3本は、どれも自宅のMacがある前提の処理でした。なので、起動役を外に出す手を選びました。

家の中の自動化は、結局ネット越しの通信で動いています。回線まわりを整えておくと、こういう仕組みも安心して回せる気がします。

契約しなくても必ず100ポイントもらえるシミュレーション 家の自動化を支える通信費も楽天モバイルで見直す

押すと楽天のログインページが開きます。ログイン後にキャンペーン内容が表示されます。

逃げ方2:起動役だけ外に出す

考え方はシンプルです。処理はWorkerに残したまま、「いつ動かすか」だけを外に任せます。外の起動役は、WorkerのURLをHTTPで叩くだけです。

僕は位置情報の同期とサイネージ更新のCronを外しました。代わりに、自宅のMacのlaunchdからWorkerのURLを叩く形に移しています。これで空き枠は3本になりました。

うれしい副作用もありました。位置情報の同期は1日1回だったのが、朝8時05分から夜20時05分まで毎時に増やせました。Cronの枠を気にしなくてよいのが大きいですね。

Worker側に受け口を作る

Worker側には、起動用のパスを用意します。大事なのは、合言葉を知っている相手だけを通すことです。

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    if (url.pathname !== "/run/location-sync") {
      return new Response("not found", { status: 404 });
    }
    const auth = request.headers.get("Authorization");
    if (auth !== `Bearer ${env.RUN_TOKEN}`) {
      return new Response("unauthorized", { status: 401 });
    }
    await syncLocation(env);
    return new Response("ok");
  },
};

トークンはコードに直接書かず、シークレットとして登録します。登録にはnpx wrangler secret put RUN_TOKENを使います。コードからはenv.RUN_TOKENで読めます。

Mac側はlaunchdで叩く

Mac側では、launchdのジョブからcurlを実行します。流れは次のとおりです。

  1. トークンを読み込み、curlでWorkerのURLを叩くシェルスクリプトを作る
  2. ~/Library/LaunchAgentsにplistを置き、実行時刻を指定する
  3. launchctlでジョブを読み込む
  4. 手動で一度実行して、Worker側のログで成功を確かめる

スクリプトの中身は、ほぼcurlの1行です。

curl -fsS --max-time 600 \
  -H "Authorization: Bearer ${RUN_TOKEN}" \
  https://example.workers.dev/run/location-sync

launchdはMacのローカル時刻で動きます。Cron TriggersのようにUTCへ直す必要がないのは、地味に楽なところです。

外から叩くときの注意点

外から起動する形には、Cron Triggersにはない注意点があります。僕が実際に引っかかった点も含めて並べておきます。

注意

URLを知っていれば誰でも叩けてしまいます。秘密トークンで認証し、トークンはシークレットに置いてください。curlのタイムアウトは、処理時間より長めに取るのが安全です。

一番ハマったのはタイムアウトです。Macから叩く処理は、2日分をまとめると約73秒かかりました。curlのタイムアウトを90秒にしていたところ、時間切れになりました。今は600秒に延ばしています。

公式によると、HTTPで起動したWorkerの実行時間に硬い上限はありません。ただ、クライアントが接続している間だけという条件付きです。切断されると、処理が途中で止まる可能性があります。なので、呼ぶ側のタイムアウトは余裕を持たせたほうがよいと思います。

もう1つはCPU時間です。Freeでは1回あたり10msまでです。ただ、fetch()やデータベースの応答待ちはCPU時間に数えられません。外部APIを待つだけの処理なら、長く見えても収まることが多いかもしれません。

逃げ方3:ディスパッチャWorkerに集約する

複数のWorkerがそれぞれCronを持っているなら、集約する手もあります。1本の「ディスパッチャ」Workerだけにスケジュールを持たせる形です。

ディスパッチャはcontroller.cronや起動時刻を見て、担当のWorkerを呼び出します。呼び出し先へは、HTTPで叩く形が分かりやすいと思います。

この方法の良い点は、Cloudflareの中で完結することです。自宅のPCが寝ていても動きます。ただ、ディスパッチャが壊れると全部の定期処理が止まります。Freeではサブリクエストが1回あたり50までなので、呼び出し先が多いときは気にしておきたいところです。

逃げ方4:有料プランに移る

いちばん素直なのは、Workers Paidに移ることです。料金ページでは、アカウントあたり月額5ドルからとされています。

上限は5本から250本に広がります。Cron起動時のCPU時間も伸びるので、重めの処理も置きやすくなります。

個人的には、家の自動化で250本も使うことはなさそうです。枠の問題だけなら、まず(1)〜(3)で様子を見る。処理の重さで困ったら有料を考える。そんな順番でよいのかなと思います。

僕が受け入れたトレードオフ

起動役をMacに移したことで、はっきり失ったものがあります。サイネージはMacが動いていないと更新されなくなりました。Macを経由しないで届く経路は、もうありません。

とはいえ、サイネージを見るのは家にいるときです。家にいるときはMacも動いていることが多いです。この前提なら受け入れられる、と判断しました。

逆に、外出中も確実に届いてほしい通知はCron Triggersに残すほうが安心だと思います。「止まっても困らないもの」から外に出していく、という線引きが大事だと感じています。

よくある失敗・落とし穴

実際にやってみて、ここは気をつけたいと思った点です。

特に3つ目は見落としがちです。デプロイ後は、ダッシュボードかWranglerの出力でスケジュールが登録されたか確認しておくと安心です。

向いている人・向いていない人

逃げ方2(起動役を外に出す)は、向き不向きがはっきりしています。

内容
向いている人常時動いている自宅PCやサーバーがある / 家にいるときだけ動けばよい処理がある / 頻度を細かく増やしたい
向いていない人外出中や旅行中も確実に動いてほしい / 自宅PCを頻繁にスリープさせる / 認証まわりを管理したくない

向いていない側なら、(1)か(3)のほうが合っているかもしれません。有料プランも選択肢です。

始める前に確認すること

よくある質問

Q. 5本の上限はWorkerごとですか?

アカウント全体で5本です。Worker 1本ごとに5本ではありません。複数のWorkerに分けても、合計で数えられます。

Q. 上限を超えるとデプロイ自体が失敗しますか?

僕の場合は、コードのデプロイは通りました。失敗したのはスケジュールの設定だけです。エラーコードは10072でした。一見成功に見えるので、出力はよく確認したほうがよいと思います。

Q. 1本の式に何個の時刻まで入れられますか?

時の欄をカンマでつなげば、分が同じ時刻をいくつでもまとめられます。ただ、分が違う時刻は同じ式では表せません。まとめすぎると、ハンドラ内の振り分けが読みにくくなる点も気をつけたいところです。

Q. controller.cronとevent.cronは違いますか?

今の公式ドキュメントではcontroller.cronで判別する形です。controllerはscheduledハンドラの第1引数です。古いコードではevent.cronと書かれていることがあります。どちらも、起動した式の文字列を見る考え方は同じです。

Q. 外から叩く場合、無料枠のリクエスト数は大丈夫ですか?

Freeでは1日10万リクエストまでです。毎時1回叩く程度なら、1日十数回なので余裕があります。ただ、他の用途と合算される点は覚えておくとよいかもしれません。

Q. 自宅PC以外に起動役を任せる方法はありますか?

外部のスケジュール実行サービスや、別のクラウドの定期実行機能から叩く方法もあります。その場合も、認証とタイムアウトの考え方は同じです。どのサービスを使うかは、止まったときの影響で選ぶのがよいと思います。

Q. 有料プランにすればCPU時間の心配もなくなりますか?

Cron起動時のCPU時間は、Paidでは間隔に応じて30秒か15分まで伸びます。Freeの10msよりかなり余裕があります。ただ、上限そのものが無くなるわけではない点には注意が必要です。

参考にした公式情報

まとめ

Cron Triggersの上限は、アカウント全体で5本です。家の自動化を続けていると、意外と早く当たります。

僕は、まず朝昼の式を1本にまとめました。次に、Macがある前提の処理だけ起動役を外に出しました。おかげで枠に余裕ができ、位置情報の同期も毎時に増やせています。

その代わり、サイネージはMac頼みになりました。どこまでを外に出すかは、止まったときに困るかどうかで決めるのがよさそうです。

ちなみに、家のサイネージの中身については学校の連絡帳をAIに読ませて家のディスプレイに反映する話に書いています。朝の情報を1枚にまとめる仕組みは朝のブリーフィングを自動生成している話にまとめました。あわせて読んでみてください。

自動化の足回りを見直すついでに、毎月の通信費も一度眺めてみるのはいかがでしょうか。

契約しなくても必ず100ポイントもらえるシミュレーション 通信費も一緒に見直すなら楽天モバイルをチェック

押すと楽天のログインページが開きます。ログイン後にキャンペーン内容が表示されます。

本記事にはアフィリエイト広告を含みます。当サイトのリンクを経由して商品・サービスへお申し込みいただいた場合、提携先企業から成果報酬を受け取ることがあります。 また、運営者は楽天グループに所属する社員であり、紹介プログラムを通じた報酬を受け取る場合があります。記事内容・評価は広告の有無にかかわらず、運営者の実体験と調査に基づき作成していますが、 上記の関係性をご理解のうえお読みください。詳しくは免責事項・アフィリエイト表記をご覧ください。

楽天モバイルの通信エリア・電波状況について気になることがある方は、公式の電波改善・調査依頼フォームからご相談いただけます。

ABOUT THE AUTHOR
まさきん

楽天グループ勤務・デジタルマーケター(FP資格保有)

40代前半、共働き・四児の父。楽天グループでデジタルマーケターとして勤務するかたわら、ファイナンシャルプランナー(FP)の資格を活かして家計管理と資産形成にも力を入れている。

プロフィールを見る

関連記事

RELATED
Gemini(Google AI Pro)のファミリー共有は家族5人まで。設定手順と範囲 AI活用

Gemini(Google AI Pro)のファミリー共有は家族5人まで。設定手順と範囲

Google AI Proは管理者のほか家族5人まで共有できます。Geminiアプリとストレージは共有でき、YouTube Premium Liteは管理者のみ。Flowの上限は家族で分け合います。設定手順と子どものアカウントの扱いを公式ヘルプで整理しました。

2026.10.13 · 読了 13分
AIサブスクの請求日と家計簿がずれる3つの理由|Claudeはアップグレードで請求日が変わる AI活用

AIサブスクの請求日と家計簿がずれる3つの理由|Claudeはアップグレードで請求日が変わる

Claudeは月の途中でMaxへ上げると請求サイクルがリセットされ、その日が新しい請求日になります。ドル建ての円換算はカード会社にデータが届いた時点で決まり、明細や家計簿の反映は数日遅れます。領収書メールを正本に月を決める5つの手順をまとめました。

2026.10.13 · 読了 13分
freee会計の未処理明細を月1回の消込便に。毎月5日7:30・3区分・上限15件で人に回す設計 AI活用

freee会計の未処理明細を月1回の消込便に。毎月5日7:30・3区分・上限15件で人に回す設計

freee会計の未処理明細が18件ほど、週次の確認6回ぶん動かないまま残っていました。毎月5日の朝7:30に自宅Macで動かす消込便の設計と、確定できる分は月1件・迷う明細は1件ずつ上限15件で人に回す線引きをまとめます。

2026.10.12 · 読了 13分
楽天モバイルに乗り換えで最大14,000ポイント 契約しなくても必ず100ポイントもらえるシミュレーション →
いますぐエントリー →