Google Apps Scriptの6分制限(タイムアウト)を回避する方法:実践ガイド

intermediate📗 Google Sheets2026-03-30| Google Apps Script / Google Sheets / Google Workspace

Error Message

Exception: Exceeded maximum execution time
#google-apps-script#タイムアウト#パフォーマンス#google-sheets

問題点Google Apps Script(GAS)を使えばGoogle Sheetsの自動化は非常に簡単になりますが、リソースは無限ではありません。プラットフォームの安定性を維持するため、Googleはスクリプトの実行時間に厳格な制限を設けています。標準的な@gmail.comアカウントの場合、スクリプトは6分以内に終了する必要があります。Google Workspaceのビジネスユーザーには、より長い30分の枠が順次与えられています。

データセットが大きくなると、この上限に達する可能性が高くなります。2万行の処理や、数十回の外部API呼び出しを行うと、割り当てられた時間を超えてしまうことがよくあります。制限時間に達するとスクリプトは即座に停止し、以下のエラーが表示されます。

Exception: Exceeded maximum execution time

真のボトルネック原因は通常、データの量そのものではなく、コードの「冗長な通信」にあります。スクリプトが getValue()setValue() を呼び出すたびに、ネットワーク経由でスプレッドシートサーバーにリクエストを送信する必要があります。これは、卵を1個買うためにスーパーへ行き、帰宅して、またすぐに次の1個を買いに行くようなものです。

以下のような、よくあるが非効率なパターンを考えてみましょう:

// 低速:「卵を1個ずつ」アプローチ
function slowProcess() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastRow = sheet.getLastRow();

  for (let i = 1; i  {
    let value = row[0];
    return [value * 2]; 
  });

  // すべてを書き戻すための1回の呼び出し
  sheet.getRange(1, 2, results.length, 1).setValues(results);
}

以前は getValue() を使用して5分かかっていたスクリプトも、このバッチ手法を使用すれば5秒以内に終了することがよくあります。

2. トリガーによる実行の連鎖低速な外部APIからデータを取得する場合など、バッチ処理だけでは不十分なこともあります。このような場合は、スクリプトを一時停止し、進捗を保存して、中断したところから再開するように設計する必要があります。PropertiesService を使用して「チェックポイント」を保存し、ScriptApp を使用して次回の実行をスケジュールします。

function processInChunks() {
  const MAX_TIME = 5 * 60 * 1000; // 5分間のセーフティバッファ
  const startTime = new Date().getTime();
  
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const props = PropertiesService.getScriptProperties();
  const startRow = parseInt(props.getProperty('LAST_ROW') || '1');
  const lastRow = sheet.getLastRow();

  for (let i = startRow; i  MAX_TIME) {
      props.setProperty('LAST_ROW', i.toString());
      createTrigger();
      return; // タイムアウトになる前に正常に終了する
    }

    // ここに重い処理を記述(例:UrlFetchApp.fetch)
    let val = sheet.getRange(i, 1).getValue();
  }

  props.deleteProperty('LAST_ROW');
  cleanUpTriggers();
}

function createTrigger() {
  ScriptApp.newTrigger('processInChunks')
    .timeBased().after(60000).create();
}

確認方法新しいシステムが動作していることを確認するために、以下の点を確認してください:

  • 実行履歴: エディタの「実行数」タブを確認します。失敗した1つの長い実行ではなく、成功した複数の短い実行が表示されるはずです。- プロパティログ: PropertiesService.getScriptProperties().getKeys() をログに出力し、行カウンターが正しく更新されているか確認します。- トリガー数: 終了後にスクリプトがトリガーを削除していることを確認してください。Googleは1つのスクリプトにつき20個までのトリガー制限を設けているため、溜まりすぎないように注意しましょう。## まとめ- API呼び出しを最小限にする: スプレッドシートとのやり取りはコストが高いですが、スクリプトエンジン内のロジックは低コストです。- 6分ルール: データが増えることが予想される場合は、最初から6分制限を考慮してスクリプトを設計しましょう。- チェックポイント: PropertiesService を使用してスクリプトに記憶を持たせ、再起動後も処理を継続できるようにします。

Related Error Notes