GEMINI LABJP
PRO35 — Gemini 3.5 Pro is reported to target July 17, though the date, context window, and pricing all remain unconfirmed by GoogleREBUILD — The model is said to be a ground-up rebuild after the 2.5 Pro architecture was scrapped over structural failures in recursive tool-calling and SVG generationFLASH35 — Gemini 3.5 Flash is the newest broadly available release, tuned for faster, lower-cost coding, agents, multimodal, and long-document workSAATHI — ATL Saathi, built on Gemini 3.5 Flash, begins piloting in 100 Indian schools as a 24/7 planning and training assistant for Tinkering Lab educatorsSEA — In Southeast Asia, nearly 70% of prompts arrive in native languages — Vietnam 89%, Thailand 87%, Indonesia 84% — and 3 in 4 requests come from mobileSHEETS — From July 15, AI Expanded Access licenses raise the usage limits for Fill with Gemini and the AI function in SheetsPRO35 — Gemini 3.5 Pro is reported to target July 17, though the date, context window, and pricing all remain unconfirmed by GoogleREBUILD — The model is said to be a ground-up rebuild after the 2.5 Pro architecture was scrapped over structural failures in recursive tool-calling and SVG generationFLASH35 — Gemini 3.5 Flash is the newest broadly available release, tuned for faster, lower-cost coding, agents, multimodal, and long-document workSAATHI — ATL Saathi, built on Gemini 3.5 Flash, begins piloting in 100 Indian schools as a 24/7 planning and training assistant for Tinkering Lab educatorsSEA — In Southeast Asia, nearly 70% of prompts arrive in native languages — Vietnam 89%, Thailand 87%, Indonesia 84% — and 3 in 4 requests come from mobileSHEETS — From July 15, AI Expanded Access licenses raise the usage limits for Fill with Gemini and the AI function in Sheets
Articles/Workspace
Workspace/2026-07-16Advanced

I Put =GEMINI() in 420 Cells. The Calls Kept Coming on Days I Never Opened the Sheet

A custom function calling Gemini from Sheets looks best the moment it starts working, and it does not grow from there. Here is what the 30-second ceiling, uncontrolled recalculation, and read-only cells actually cost, measured, plus the code to move to a write-back design.

gemini-workspace5apps-script10google-sheetscost-controlindie-development5

Premium Article

The cell note just said Exceeded maximum execution time (line 0). Thirty-seven cells out of 420 showed #ERROR!, scattered with no pattern I could see. Same prompt, same model, inputs of roughly the same length. Nothing was wrong with those particular rows. What was wrong was the arrangement: 420 formulas sitting next to each other in a column.

I had been collecting app review text in a spreadsheet — column C for the review, column D for =GEMINI_SUMMARY(C2). As an indie developer running this kind of thing solo, the appeal is obvious: no deployment, no backend, and the answer appears in the cell while you watch.

Ten rows worked beautifully. Dragging the formula down to 420 rows surfaced everything this shape had been hiding.

The #ERROR! cells were not the real problem. At the end of that week I looked at the usage numbers: I had written 420 formulas, and the script had made 1,180 calls. The count went up on mornings when nobody had touched the file.

Every cell is its own separate call

The optimization section of the official documentation states the core of it plainly: each time a custom function is used in a spreadsheet, Sheets makes a separate call to the Apps Script server. Dozens, hundreds, or thousands of custom function calls in one sheet make that process slow.

So pasting =GEMINI_SUMMARY(C2) into 420 cells is not one job processing 420 rows. It is 420 independent executions embedded in a spreadsheet, each with its own 30-second budget.

The difference shows up when things fail, and when things amplify. A 420-row batch can hold "how far did we get" in one place. Four hundred and twenty independent executions have no concept of progress at all. There are only cells that happen to contain a value and cells that happen to say #ERROR!.

Google publishes a custom function sample that fact-checks statements using an ADK agent and a Gemini model, and it is a good on-ramp. The trouble starts when you try to extend the on-ramp into a road.

The calls that arrive while you sleep

Recalculation does not happen when you decide it should. The documentation is specific: to trigger recalculation you must pass a referenced cell or range directly as an argument; otherwise the function will not recalculate until you edit the formula or change a referenced cell's value.

Read that the other way around. As long as you pass a referenced cell directly, every change to that reference triggers a fresh call. In my sheet, touching column C re-ran column D. Fixing a typo. Inserting a language column. Moving a column to sort. Every one of those is an edit.

There is a related constraint worth knowing: arguments must be deterministic. Volatile built-ins like NOW() or RAND() cannot be passed to a custom function — try it and the cell shows Loading... forever. The natural workaround is to park a fixed timestamp in a cell instead, and the moment you refresh that timestamp, you have pulled the recalculation trigger yourself.

Here is my week, counted. These are my numbers on my sheet, and they will move depending on how you work. Treat them as a shape to re-measure, not a benchmark.

TriggerTimesRows recalculatedCalls
Initial fill across 420 rows1420420
Typo fixes in column C (one cell at a time)232323
Inserting and removing a language column2420654*
Saving prompt tweaks in the script483
Total1,180

* Not every row re-runs every time; some keep their cached value. That inconsistency is exactly what makes this hard to see — the sheet never tells you how many times it called.

Formulas written: 420. Actual calls: 1,180. A 2.8x multiplier. What matters is not the size of the multiplier but that it is disconnected from anything I chose to do. Inserting one column — an action with no apparent cost — quietly billed a few hundred requests.

To count it on your own sheet, one line on the calling side is enough.

/**
 * Summarizes review text (instrumented — this shape is not for production).
 *
 * @param {string} text The review body to summarize.
 * @return {string} The summary text.
 * @customfunction
 */
function GEMINI_SUMMARY(text) {
  // Record the fact of the call first. Count them in the Apps Script executions view.
  console.log('GEMINI_SUMMARY invoked len=%s', String(text).length);
 
  const key = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
  const url = 'https://generativelanguage.googleapis.com/v1beta/models/'
    + 'gemini-flash-latest:generateContent?key=' + key;
 
  const res = UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({
      contents: [{ parts: [{ text: 'Summarize this review in one sentence.\n\n' + text }] }],
    }),
    muteHttpExceptions: true,
  });
 
  if (res.getResponseCode() !== 200) {
    // A custom function can only return a value. The cause dies here.
    return '#GEMINI_ERROR';
  }
  const json = JSON.parse(res.getContentText());
  return json.candidates[0].content.parts[0].text.trim();
}

Paste it, use the sheet normally for a week, then compare the execution count in the Apps Script dashboard against the number of formulas in the sheet. For me, that gap settled the argument faster than any reasoning about architecture did.

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
A measurement recipe for counting the recalculation amplification your sheet generates on its own, plus the breakdown behind a measured 2.8x on 420 rows
Why the 30-second custom function ceiling is a different limit from the 6-minute one, and how to turn your per-row latency into a hard cap on rows per call
Complete menu-driven batch code for moving from formulas-in-cells to a status column with written-back values, and a decision table for when a custom function is still the right shape
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 $10 for lifetime access
View Membership →

Related Articles

Workspace2026-07-10
Resuming Large Gemini Files API Uploads Across the Apps Script 6-Minute Limit
Sending a few hundred megabytes from Drive to the Gemini Files API through Apps Script means fighting a 6-minute execution cap and payload limits. Here is how to decompose resumable upload into start, upload, query and finalize so a killed run never loses progress.
Workspace2026-06-29
When Apps Script Time-Driven Triggers Quietly Run Out: Consolidating Gemini Automations into One Dispatcher
Apps Script caps you at 20 triggers per user and a daily total trigger-runtime budget. Here is how to stop your Gemini automations from silently dying as you add more, using a single dispatcher, a schedule table, and an external heartbeat.
Workspace2026-04-28
Build a $500/Month Side Income with Google Workspace × Gemini Automation — 3 Ready-to-Sell Templates
Turn Google Workspace automation into a recurring side income by selling Gemini-powered services to small businesses. Includes 3 deployable templates and a pricing blueprint.
📚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
See all →