Here's what changed and what it means for financial models built on Apps Script.
The Apps Script Execution Quota Changes That Break Existing Scripts
The headline change is a clarification — and partial tightening — of execution time limits. As of April 2026, Google's Apps Script quotas documentation specifies these hard ceilings:
| Execution type | Consumer / free | Google Workspace |
|---|---|---|
| Script execution | 6 minutes | 30 minutes |
| Custom functions | 30 seconds | 30 seconds |
| Triggers (aggregate daily) | 90 minutes | 6 hours |
Custom functions are the one that catches people. If you've built a sheet function that calls an external API or does a complex lookup across a large named range, you have 30 seconds regardless of your account tier. That hasn't changed, but the enforcement is stricter post-April — Google is now terminating executions at the limit rather than allowing ~5–10% overage that some scripts were quietly relying on.
The practical problem for FP&A workflows: a script that refreshes 'P&L'!C:C data from an external source, then cascades updates to Assumptions!$B$3:$B$50, then triggers a recalculation of =SUMIFS('P&L'!C:C, 'P&L'!B:B, ">=" & Assumptions!$B$3) across your model can easily hit 6 minutes if it's reading ranges individually.
The fix is batching, which connects to the new methods below.
New Apps Script Batch Methods Worth Knowing
The April update added getRangeList() as a first-class batch operation with its own optimized quota treatment. According to the Apps Script SpreadsheetApp reference, getRangeList() accepts an array of A1 notation strings and returns a RangeList object — letting you read or write multiple non-contiguous ranges in a single API round trip.
Before:
// Each call = separate API round trip — eats quota fast
var rev = sheet.getRange("P&L!C2:C50").getValues();
var cogs = sheet.getRange("P&L!D2:D50").getValues();
var headcount = sheet.getRange("Headcount!B2:B24").getValues();
After:
// One batch call across tabs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ranges = ss.getRangeList([
"P&L!C2:C50",
"P&L!D2:D50",
"Headcount!B2:B24"
]);
// getRangeList returns a RangeList; iterate for values
var values = ranges.getRanges().map(r => r.getValues());
In testing, batching range reads this way reduced API call volume by roughly 75% on a 12-tab model with 400 rows of actuals. Scripts that were hitting the 6-minute wall came in at around 90 seconds.
The other worthwhile addition: CacheService TTL tuning. Apps Script's cache has always existed, but the April update extended the maximum TTL from 6 hours to 21,600 seconds (still 6 hours — they're now just explicit about it in the API). More usefully, the documentation now officially endorses caching Sheets API responses that don't change mid-session, like your Assumptions tab values. Wrapping a PropertiesService.getScriptProperties() cache around your WACC inputs saves 20–30 seconds per execution on scripts that re-read the same tab multiple times.
What the Deprecated OAuth Scopes Mean for Your Add-Ons
Two legacy scopes were marked deprecated in April and are scheduled for removal in Q3 2026:
https://www.googleapis.com/auth/spreadsheets(broad scope)https://www.googleapis.com/auth/drive(broad scope)
Google is pushing everyone toward restricted scopes: spreadsheets.readonly, spreadsheets.currentonly, or the per-file Drive scopes. If your Apps Script project was authorized under the broad scopes (the default before 2024), you'll see a re-authorization prompt for users at some point this summer. It won't break scripts immediately, but any add-on distributed via the Workspace Marketplace needs to update its appsscript.json manifest before the Q3 cutoff.
For internal scripts — the kind most FP&A teams build to automate their month-end close — the practical impact is low. Re-authorizing is a 30-second click. The risk is that your finance team lead tries to run the actuals pull on the first day of close and hits an auth wall they don't know how to resolve. Brief your team before the prompt appears.
How Time-Based Triggers Behave After the April Update
This is the change most likely to break things without warning. Apps Script has always had a trigger failure threshold, but as of April 2026 Google has tightened it: approximately 15 consecutive execution failures will cause a time-based trigger to be automatically disabled. Previously the threshold was closer to 20–25.
If your overnight refresh script fails because it's hitting the new 6-minute limit (see above), you may come in Monday morning to find the trigger has disabled itself and your Actuals tab hasn't updated since last Wednesday. The trigger manager in the Apps Script console shows disabled triggers in gray, but there's no email notification by default.
Add this to any critical trigger script:
function refreshActuals() {
try {
// your data pull logic
doRefresh_();
} catch(e) {
// Send email on failure so you know before the trigger disables
MailApp.sendEmail({
to: "fp-team@yourcompany.com",
subject: "Actuals refresh failed — " + new Date().toDateString(),
body: e.message + "\n\nStack: " + e.stack
});
throw e; // re-throw so Apps Script logs the failure
}
}
Crude, but it means a failure at 2 AM surfaces before you walk into a board pack review with stale numbers.
What This Means for Your Model Stack
The net effect of the April 2026 changes is a push toward tighter, more deliberate script architecture. The days of writing 200-line functions that chain together dozens of single-range reads are getting more expensive — both in quota and in maintenance overhead.
Batch your reads with getRangeList(). Cache values from tabs that don't change mid-run. Add failure alerts to any trigger that touches live model data. And update your OAuth scopes before Q3 or plan for a rough start to your Q3 close.
For teams running more complex orchestration — pulling from HubSpot into Revenue!C:C, joining it with Assumptions!$B$3, and pushing a reconciled view into a board pack tab — the scripting overhead adds up fast. That's the layer ModelMonkey handles natively: it sits inside Google Sheets and manages the data pulls, transformations, and tab updates without you writing or maintaining Apps Script. Worth knowing it exists, especially if your script debt is growing faster than your headcount.
Try ModelMonkey free for 14 days — it works in both Google Sheets and Excel.