◉GEMINI LABJP
●3.8 FLASH — 3.7 Flash was deprecated on Oct 8. Requests to the old model are routed to 3.8 Flash automatically●NANO 2.1 — gemini-nano-banana-2.1 is GA. gemini-3.1-flash-image is deprecated with no shutdown date yet●DEADLINE — veo-3.1 previews and gemini-omni-flash-preview shut down Oct 22; the Deep Research agent follows Oct 23 (12-13 days left)●Q&A — Users report Gemini CLI marks a subagent run as a success even after it stops at MAX_TURNS●TTS/LIVE — 2.5-era audio and TTS previews shut down Nov 17, 38 days left●NEW — Deprecated with no shutdown date? Re-pick your image-model target with three conditions●3.8 FLASH — 3.7 Flash was deprecated on Oct 8. Requests to the old model are routed to 3.8 Flash automatically●NANO 2.1 — gemini-nano-banana-2.1 is GA. gemini-3.1-flash-image is deprecated with no shutdown date yet●DEADLINE — veo-3.1 previews and gemini-omni-flash-preview shut down Oct 22; the Deep Research agent follows Oct 23 (12-13 days left)●Q&A — Users report Gemini CLI marks a subagent run as a success even after it stops at MAX_TURNS●TTS/LIVE — 2.5-era audio and TTS previews shut down Nov 17, 38 days left●NEW — Deprecated with no shutdown date? Re-pick your image-model target with three conditions
Articles/Workspace
◧ Workspace/2026-07-08Advanced

Your Apps Script Gemini Automation Fails Every Month-End — Budgeting Against the UrlFetch Daily Quota

Apps Script automations that call Gemini stall on the UrlFetch daily call quota — a separate ceiling from the 6-minute limit and trigger counts. Here is a daily budget governor with backlog carry-over that keeps the job running on busy days, with working code and a verified simulation.

Apps Script12Gemini API247UrlFetchAppGoogle Workspace21automation54

✦ Premium Article

Every month-end, the same automation quietly died.

As an indie developer I run a handful of apps on my own, and a few of them lean on Apps Script to call Gemini — drafting replies to user reviews, tagging newly added wallpapers. On ordinary days everything flows without a hitch. But on a few days each month, an unfamiliar error showed up in the execution log, always the day after reviews had surged.

My first guess was rate limiting (429). But a 429 should be absorbed by exponential backoff. Following the log, I found the failure was not on Gemini's side at all — it was on Apps Script's. Service invoked too many times for one day: urlfetch. I had hit the UrlFetch daily call quota.

This article focuses on that third ceiling: the daily call quota of UrlFetchApp, which is neither the 6-minute runtime limit nor the trigger-count limit. It stays invisible while volume is steady and only shows its teeth on busy days. I will lay out a design that absorbs it quietly — a daily budget governor plus backlog carry-over — with working code and a verified simulation.

The third ceiling is "how many times can you call UrlFetch in a day"

As an Apps Script Gemini automation grows, it hits separate limits in sequence. Runtime and triggers are the well-known ones; the UrlFetch daily quota tends to hide behind them.

Limit you hitWhat is cappedconsumer (gmail.com)Google Workspace
Execution timeLongest single execution6 min / execution30 min / execution
Total trigger runtimeTrigger runtime per day90 min / day6 hr / day
UrlFetch daily callsUrlFetch calls per day20,000 / day100,000 / day

The runtime wall can be crossed by splitting work and continuing in the next trigger. The trigger-count wall can be crossed by consolidating into a single dispatcher. But the UrlFetch daily quota is different in kind: splitting or consolidating does not change the total number of calls you can issue in one day. If your design calls Gemini once per item, the number of items you process that day maps directly onto the quota.

I covered the runtime and trigger bottlenecks in earlier articles. This one is about the problem that remains even after you have solved both — how many calls you can make in a day. For the related designs, see crossing the 6-minute limit with chunking and idempotency and consolidating time-driven triggers into one dispatcher; together they make clear that the three ceilings are genuinely separate.

The naive version melts the quota on a busy day

Here is the naive version I wrote first. On each trigger, pick up every unprocessed row and send it to Gemini — on ordinary days, that is enough.

// Before: process all pending each run (fails on busy days)
function enrichPendingRows() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('reviews');
  const rows = sheet.getDataRange().getValues();
 
  for (let i = 1; i < rows.length; i++) {
    if (rows[i][STATUS_COL]) continue;      // skip done rows
    const draft = callGemini(rows[i][TEXT_COL]);   // one UrlFetch per item
    sheet.getRange(i + 1, STATUS_COL + 1).setValue('done');
    sheet.getRange(i + 1, DRAFT_COL + 1).setValue(draft);
  }
}
 
function callGemini(text) {
  const res = UrlFetchApp.fetch(GEMINI_ENDPOINT, {
    method: 'post',
    contentType: 'application/json',
    headers: { 'x-goog-api-key': 'YOUR_API_KEY' },
    payload: JSON.stringify({ contents: [{ parts: [{ text: text }] }] }),
    muteHttpExceptions: true,
  });
  return JSON.parse(res.getContentText()).candidates[0].content.parts[0].text;
}

This code has a weakness that always surfaces on a busy day: there is no cap on the number of pending items. At a usual 3,000 items/day it takes just over 3,000 UrlFetch calls. But the day after a feature launch adds 40,000 reviews, it tries to process 43,000 at once and issues over 46,000 UrlFetch calls. Well past the 20,000 wall, it hits the urlfetch daily limit and throws mid-run.

Worse, the failure point moves around. Which item it dies on depends on how many UrlFetch calls other scripts made that day. Whatever stopped short carries over to the next day — but the naive version has no notion of "how far did I get" in budget terms, so the next day it fires all pending items at once again and hits the same wall. That was the loop I ran, a few days every month-end.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Understand, from reproducible code, how the UrlFetch daily call quota (20,000 calls/day on consumer accounts) is a third ceiling — distinct from the 6-minute runtime and trigger-count limits — that only bites on high-volume days
✦Copy a complete Apps Script token-bucket governor that keeps a daily budget ledger in Script Properties and resets it on the timezone boundary, not UTC
✦Verify with a deterministic simulation (backlog clears three days after a spike) that carrying work over to the next day converges instead of snowballing
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

◧ Workspace2026-10-03
Estimating a Sheets-Driven Gemini Bill Across the Year-End Price Switch with Apps Script
If you call the Gemini API from a spreadsheet, log the token counts per call and estimate the month in two columns: the intro price that ends on December 31, 2026 and the standard price from January 1, 2027. Apps Script, with real output.
◧ Workspace2026-09-08
Four New Steps Landed in Workspace Studio, and I Am Opening the Reply Ones a Week Later
Workspace Studio gained Drive copy and move steps plus Chat and email reply steps. Using the rollout dates, where admin controls arrive before the features, here is how I separate the reversible actions from the ones I cannot take back.
◧ Workspace2026-09-01
When a New Gemini Feature Hasn't Reached Your Workspace, Here's How to Tell Waiting From Broken
A step-by-step way to decide whether a missing Gemini feature in Google Workspace is still rolling out or actually misconfigured, using release tracks and rollout pace, plus a small Apps Script ledger that does the counting for you.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links