gas 実行時間 制限|6分で止まる処理を分けて回す設計
この記事のポイント
1回の実行時間の上限は動かせないので、変えるのは「1回でどこまでやるか」の決め方です。範囲・時間・役割・やらないことの4つで分けられますが、どの分け方も処理済みを記録する列を1つ持つことが前提になります。また、1回6分より先にトリガーの合計実行時間やメール宛先数の日次上限が効くことがあるため、業務で使うアカウントの種類を先に決めておきます。
「昨日までは動いていたのに、途中で止まるようになったんです」
スプレッドシートで回している業務を見せてもらうとき、よく聞く相談です。半年前に作った集計や転記の仕組みが、ある日から最後まで終わらなくなる。画面には赤いメッセージが出ているのですが、業務側の人にとっては何が起きたのか分かりません。作った人がすでに社内にいないこともあります。
このとき起きているのはたいてい壊れたのではなく、上限に当たっただけです。Google Apps Script(GAS)には1回の実行時間に上限があり、シートの行が増えていけばいつかそこに届きます。仕組みが古くなったのでも、書き方が間違っていたのでもなく、対象が増えたという業務の変化が上限として現れています。
なので、まずやるべきなのは書き方を変えることではありません。1回の実行でどこまでやるかを業務として決めることです。この記事では、Googleが公表している上限を確認したうえで、業務側で処理をどう分けるか、そして分けても足りなくなったときの境目をどこに置くかを整理します。
Googleが公表している上限
まず数字を押さえます。以下は Google の公式ページに記載されている値です(2026年8月時点で確認したもの)。
| 項目 | 一般のGoogleアカウント | Google Workspace | 業務で当たる場面 |
|---|---|---|---|
| Script runtime(1回の実行時間) | 6分 | 6分 | 行が増えたシートを全件まとめて処理しているとき |
| Custom function runtime(カスタム関数) | 30秒 | 30秒 | セルに自作の関数を書き、それを大量の行にコピーしているとき |
| Triggers total runtime(トリガーの合計実行時間) | 90分/日 | 6時間/日 | 数分おきの自動実行を何本も仕掛けているとき |
| Email recipients(メール宛先数) | 100/日 | 1,500/日 | 一斉送信やリマインドを自動化しているとき |
| URL Fetch calls | 20,000/日 | 100,000/日 | 行ごとに外部のサービスへ問い合わせているとき |
| Simultaneous executions(同時実行) | 30/ユーザー(スクリプトあたり最大1,000) | 同じ | 複数人が同じシートのボタンを同時に押すとき |
出典は Google の公式ページ Quotas for Google Services(developers.google.com)です。上の表は、2026年8月時点でこのページに記載されていた値をそのまま引いています。
Googleは公式ページで、これらの上限は予告なく変更される場合があると明記しています。実装する前に必ず公式ページの現在の値を確認してください。この記事の数字も、確認した時点のものとして読んでいただくのが安全です。
表を見て気づくのは、1回の実行時間はアカウントの種類で差がない一方、差が大きいのはトリガーの合計実行時間とメール宛先数という点です。つまり「6分で止まる」問題はどのアカウントでも同じように起きますが、日単位の余裕はまったく違います。ここは後半でもう一度触れます。
上限に当たるのは「処理が重い」からではなく、対象が増えたから
6分という上限は固定です。動かせないので、当たるかどうかを決めているのは1回で触る行数のほうです。作った当初は数百行だったシートが数千行になれば、同じ処理でも時間は伸びます。「処理が重くなった」のではなく、対象が増えたのです。
相談を受けて中を見ると、当たり方はだいたい次の3つの形に分かれます。
- シートを1行ずつ読み書きしている:1行処理するたびにシートへ取りに行き、書きに戻る。読み書きの回数が行数に比例して増えるので、行が増えた分だけそのまま時間が伸びます
- 全件を毎回やり直している:前回どこまで終わったかを持っていないため、毎回1行目から始める。終わった行を何度も作り直しているので、業務としては同じことをしているのに時間だけが増えます
- 1回の実行の中で外部への問い合わせを行数ぶん繰り返している:住所から情報を引く、他のサービスに投げる、といった処理を行ごとに呼ぶ。1件あたりは短くても、待ち時間が行数ぶん積み上がります
技術的にはそれぞれ別の話ですが、原因はひとつだと考えています。1回の実行で触る対象を決めていないことです。「シートにある分を全部やる」という設計は、シートが増えないうちは正しく動きます。増える前提の業務では、いつか必ず上限に届きます。
逆に言えば、対象の決め方を先に決めておけば、シートの行が増えていっても1回の実行時間は変わりません。ここから先が、この記事の本題です。
業務として分ける4つの分け方
分け方は4つあります。どれを選ぶかはコードの話ではなく、業務側で何を決められるかで決まります。
| 分け方 | 何を決めておく必要があるか | 向いている業務 |
|---|---|---|
| 範囲で分ける | 1回で処理する件数の上限。そして「未処理」をどう見分けるか(処理済みの印を置く列) | 未処理の行が積み上がる転記・照合・ファイル生成 |
| 時間で分ける | どれくらい遅れてよいか(許容できる遅れ)。それに合う実行の頻度 | その日のうちに終われば足りる集計・日次のまとめ |
| 役割で分ける | どこまで終わったら次に渡すか(受け渡しの状態を持つ列) | 集める→判定する→送る/作る、と工程が続く業務 |
| やらないことを決める | 触らない範囲の業務ルール(例:締めた月の行は作り直さない) | 過去分も含めて毎回全件を作り直している集計 |
範囲で分けるは、いちばん素直な方法です。未処理の行を上から一定件数だけ処理し、残りは次の実行に回します。決めなければいけないのは件数そのものより、「未処理」をどう見分けるかです。ここが決まっていないと分けられません。
時間で分けるは、実行の頻度を上げて1回を軽くする方法です。ここで決めるのは技術ではなく、遅れの許容です。「反響への通知は5分以内」「請求の集計は翌朝でよい」と業務側で線を引ければ、必要な頻度が決まります。逆にこれを決めないまま「早いほうがいい」で頻度を上げると、後述する日次の上限に当たります。
役割で分けるは、集める処理と、送る処理/作る処理を別のスクリプトに分けるやり方です。ひとつの実行の中で全部やろうとすると、途中で止まったときにどこまで進んだのか分からなくなります。工程を分けておけば、止まった工程だけをやり直せます。決めるのは「どこまで終わったら次に渡すか」で、これも列として持つ必要があります。
やらないことを決めるは見落とされがちですが、効き方がいちばん大きい場合があります。毎回全件を作り直している集計は、たいてい過去分まで作り直しています。締めた月の行は触らないと決めれば、対象は今月分だけになり、上限からいったん離れます。これは書き方の工夫ではなく業務ルールの決定です。
4つを並べて見ると、共通点があります。どの分け方も処理済みかどうかを記録する列を1つ持つことが前提になっています。範囲で分けるには未処理を見分ける必要があり、役割で分けるには受け渡しの状態が必要で、やらないことを決めるにも締めたかどうかの印が要ります。列がないと、そもそも分けられません。
つまりこれは技術の話ではなく、業務プロセスの構造化です。「この業務では1件がどういう状態を通って完了するのか」を決め、それをシートの上で見えるようにする。私たちがコードより先にここを整えるのは、状態が決まっていない業務はどんな書き方をしても分けられないからです。どの業務にどんな状態があるかを洗い出す進め方は業務棚卸しの手順で整理しています。
考え方が分かる最小のコード
「範囲で分ける」がどういう形になるか、最小の例だけ置いておきます。
function processUnprocessed() {
const sheet = SpreadsheetApp.getActiveSheet();
const rows = sheet.getDataRange().getValues();
let count = 0;
for (let i = 1; i < rows.length && count < 100; i++) {
if (rows[i][5] === "済") continue;
sheet.getRange(i + 1, 6).setValue("済");
count++;
}
}やっているのは3つだけです。処理済みの印がある行は飛ばす。一定件数に達したらそこで終わる。終わった行に印を置く。あとは同じ処理を繰り返し呼べば、続きから進みます。
書き方の工夫はほかにもありますが、この記事では深追いしません。ここで見てほしいのは、コードが短いことです。難しいのは書くことではなく、印を置く列を業務として決めることのほうだと考えています。
トリガーの合計時間と、メール宛先数のほうが先に効くことがある
1回6分の話ばかりしてきましたが、実務では日単位の上限が先に効くことがあります。分けたはずなのに止まる、という相談の何割かはこちらです。
- 細かく回すと、トリガーの合計実行時間を使い切る:1回を軽くするために5分おきに動かすと、1回が短くても合計は積み上がります。一般のGoogleアカウントは90分/日、Google Workspaceは6時間/日と公表されています。自動実行を何本も仕掛けている場合、それらの合計であることに注意が必要です
- 一斉送信を組むと、メール宛先数の上限に当たる:一般のGoogleアカウントは100/日、Google Workspaceは1,500/日です。宛先の数で数えるので、1通に複数人を入れている場合も積み上がります
通知そのものの設計、つまり誰に何をどういう条件で送るかは別の論点になるので、メールを送る前に決める判定条件のほうにまとめています。送る条件を絞ることは、上限対策としても効きます。
ここから言えるのは、業務で使うなら先に決めておくことがあるということです。Google Workspaceを前提にするのか、それとも件数と頻度を業務側で抑えるのか。一般のGoogleアカウントで組み始めると、1回6分より先に日次の上限に届きます。動かし始めてから気づくと、業務が止まっている状態で調べることになります。
上限を回避するのではなく、スプレッドシートを卒業する境目
分け方を工夫すれば回る範囲はかなり広く、実際にほとんどの業務はスプレッドシートのままで足ります。GASでどこまで任せられるかの全体像はgasでできることで整理しています。
ただ、分けても足りない状態になることはあります。それは書き方の問題ではなく、扱っている量や求められる確かさが、スプレッドシートの想定を超えているサインだと見ています。判断できる形にすると、境目は次の3つです。
- 分け方を増やしても翌月にまた当たる:件数を絞り、頻度を落とし、やらない範囲も決めた。それでも翌月また止まる。これは量が増え続けている業務なので、上限との追いかけっこが終わりません
- 誰がいつ何を変えたかを追う必要が出た:金額や契約内容のように、あとから「なぜこの値なのか」を説明しなければならないデータが入ってきた。シートは誰でも直せるので、履歴を残す用途には向きません
- 失敗したときに手で直す時間のほうが長くなった:処理が止まると業務が止まり、誰かが印を確認して手で埋めている。自動化していた時間より、後始末の時間のほうが長くなっている状態です
どこに移すかの判断は表計算で回している業務をどこから作り替えるかと、SaaSを買うか自分たちで組むかを比べた効率化ツールの選び方で整理しています。
強調しておきたいのは、全部を作り替える必要はないということです。上の3つに当たっているのは、たいてい業務の一部です。履歴を残す必要が出た部分だけを外に出し、残りはシートのまま置いておく。この形がいちばん現実的だと考えています。全部を一度に移すと、作った人しか触れない仕組みが別の場所にできるだけになりがちです。
まとめ
1回の実行時間の上限は変えられません。だから変えるのは、1回で触る対象の決め方です。範囲で分ける、時間で分ける、役割で分ける、やらないことを決める—この4つのどれを選ぶかは、業務側で何を決められるかで決まります。
そして4つとも、処理済みを記録する列を1つ持つだけで使えるようになります。逆にこの列がないと、どの分け方も成立しません。ここが技術ではなく業務プロセスの構造化にあたる部分です。
あわせて、1回6分より先にトリガーの合計実行時間やメール宛先数が効くことがあります。業務で使うなら、どのアカウントで動かすのかと、件数・頻度をどこまで抑えるのかを先に決めてください。数値は変わる可能性があるので、実装前に必ず Googleの公式ページで現在の値を確認するのが前提です。
それでも分けても足りなくなったら、そのときは全体ではなく、当たった要件だけを外に出す。まずは今止まっている処理について、「1回でどこまでやるか」が決まっているかを確かめるところからで十分だと思います。
よくある質問
GASの実行時間の上限は何分ですか?
Googleの公式ページには、1回のスクリプト実行が6分と記載されています(2026年8月時点で https://developers.google.com/apps-script/guides/services/quotas に記載されていた値)。カスタム関数はこれとは別で30秒です。なお公式ページには、これらの上限は予告なく変更される場合があると明記されているため、実装する前に必ず現在の値をご確認ください。
上限を引き上げることはできますか?
私たちは、上限を引き上げる方法があると断定できる情報を確認できていません。公式ページに上限として公表されている値がある、という前提で設計するのが安全だと考えています。ただし1回の実行時間とは別に、日単位の上限はアカウントの種類で差があります。トリガーの合計実行時間は一般のGoogleアカウントで90分/日、Google Workspaceで6時間/日、メール宛先数は一般で100/日、Workspaceで1,500/日と公表されています。業務で使うなら、まずどちらのアカウントで動かすのかを先に決めてください。
処理が途中で止まったとき、データはどうなりますか?
途中まで書き込まれた状態で残ります。ここで問題になるのは、どこまで終わったかを記録していない場合です。次に動かしたときに最初からやり直すと、前半は二重に処理され、後半は結果的に抜けることがあります。処理済みかどうかを記録する列を1つ持っておくと、止まっても続きから再開できます。
5分おきのトリガーで回して大丈夫ですか?
1回の実行が短くても、トリガーの合計実行時間という日単位の上限があります。公式ページには一般のGoogleアカウントで90分/日、Google Workspaceで6時間/日と記載されています。細かく回すほどこの合計を使うので、頻度を上げる前に「どれくらい遅れてよい業務か」を決めて、必要な頻度まで落とすほうが安定します。
上限に当たり始めたら、システムに移すべきですか?
すぐ全部を作り替える必要はありません。分け方を工夫すれば回る範囲は広く、実際に多くの業務はスプレッドシートのままで足ります。移すことを検討したいのは、分け方を増やしても翌月にまた当たる(量が増え続けている)、誰がいつ何を変えたかを追う必要が出た、失敗したときに手で直す時間のほうが長くなった、というサインが出たときです。その場合も全体ではなく、当たっている要件だけを外に出すのが現実的です。
泉 款太(いずみ かんた)
株式会社SalesDock 代表取締役
慶應義塾大学法学部卒。スタートアップ、ラクスル、リクルート(SUUMO)を経て2025年に独立。 中小企業の経営・営業・業務・データをつなぐ事業基盤の設計と実装を支援。 不動産・製造業・クリニックを中心に30社以上の業務改善に携わる。
代表メッセージを読む →