TriggerShelf

Error fix

Fix "Exceeded maximum execution time" in Apps Script

Trigger: Time-drivenServices: PropertiesServiceMock-tested: Nov 2026

Exceeded maximum execution time

Google documents a six minute limit per execution. Stop at 4.5 minutes, save the next index, and let the next triggered run continue.

Set it up

  1. Move your row loop into processInBatches.
  2. Add a time-driven trigger every 10 minutes for the function that calls it.
  3. The progress is stored in script properties and cleared when finished.

The script

/**
 * Fix: "Exceeded maximum execution time".
 * Work in a time budget, remember where you stopped, and let the next run continue.
 */
var BUDGET_MS = 4.5 * 60 * 1000;

function processInBatches(items, handle, now) {
  now = now || function () { return Date.now(); };
  var props = PropertiesService.getScriptProperties();
  var start = now();
  var i = Number(props.getProperty('nextIndex') || 0);
  while (i < items.length) {
    if (now() - start > BUDGET_MS) {
      props.setProperty('nextIndex', String(i));
      return { done: false, next: i };
    }
    handle(items[i]);
    i++;
  }
  props.deleteProperty('nextIndex');
  return { done: true, next: i };
}
Test status. 3 of 3 automated checks pass, run Nov 2026 against simulated Google services. This recipe has not yet been run inside a live Google account. Test it on a copy of your sheet first.

What you should see

runprocessednext index
1812812
22,188done

Run 1 stops at 812 of 3,000. Run 2 resumes. Sample values, not output from a real account.

Common errors and fixes

The job never finishes
Each run must make progress. Check that handle(item) does not throw on the same row forever.
It restarts from row one
nextIndex was deleted. Do not clear script properties while it runs.

Permissions. Running this script asks you to grant Google permissions for the services listed above, to your own script. TriggerShelf never receives your Google data. See the permissions table. Google will show "Google hasn't verified this app"; that is expected for a script you paste yourself.