The short answer. There is no single number, because every method has a different wall:
- Google's
=AI()function: 350 cells per action, plus a lockout you cannot see coming. - An Apps Script custom function: 30 seconds per call.
- An Apps Script batch job: 6 minutes per run, then a daily trigger budget.
- Off-platform processing: no cell cap. The constraint becomes cost per row.
The spreadsheet's own 10-million-cell limit is almost never the one you hit.
"How many rows can I run AI on in a Google Sheet" has no answer until you say how you are running it. The spreadsheet can hold the rows comfortably. The question is which mechanism is doing the work, and each one fails at a completely different scale, for reasons that have nothing to do with each other.
The four ceilings, side by side
| Method | Hard limit | Comfortable up to | Failure mode |
|---|---|---|---|
Google =AI() | 350 cells per generate | A few hundred rows | Silent partial fill, then a 24-hour lockout |
| Apps Script custom function | 30 seconds per call | Tens of rows | Timeout that reads as flakiness |
| Apps Script batch + triggers | 6 min/run, 90 min-6 h/day | 1,000 to 5,000 rows/day | Killed mid-row unless you checkpoint |
| Add-on with your own API key | Your provider's rate limit | Thousands | 429s, usually without retries |
| Off-platform batch runner | None structural | Tens of thousands | Cost, and rows that legitimately fail |
Why the spreadsheet's own limit is a red herring
A Google spreadsheet holds up to 10 million cells across all its tabs. For a lead list that is roughly 500,000 rows at 20 columns, and nobody reaches it by accident.
Every other limit above bites thousands of times earlier. You will hit the 350-cell cap at row 351, the custom function timeout at whatever row the recalculation queue gets congested, and the trigger budget within a day. The document limit is not your problem, which is worth knowing because it is the number most articles lead with.
Working out your actual ceiling
Two numbers decide everything: seconds per row, and rows.
A model call that takes 2 seconds, run serially, processes 180 rows in a 6-minute Apps Script execution. On a consumer account's 90-minute daily trigger budget that is about 2,700 rows per day, assuming nothing else uses triggers. On Workspace's 6 hours, about 10,800.
Those numbers move if you parallelise, and Apps Script permits 30 simultaneous executions per user, so a well-built fan-out does better. It also gets worse the moment a call takes 8 seconds instead of 2, which happens with longer prompts and larger models.
The useful move is to time one row before designing anything. Multiply. If the answer is over an hour of wall-clock, you are building a job scheduler, and you should decide deliberately whether that is the thing you want to be building.
What changes at each scale
Up to a few hundred rows
Anything works. Use the built-in function, batch it in blocks, accept the manual step. Adding tooling here is overhead for its own sake.
One to ten thousand rows
This is where it gets interesting, and where the failure you should be planning for changes. It stops being "does it finish" and becomes "do I know which rows did not".
At 4,000 rows, a 3% failure rate is 120 rows. If those rows are blank, they are indistinguishable from rows the model legitimately had nothing to say about, and they will be found by whoever uses the list, in the form of an email addressed to Hi ,. Per-row status stops being a nicety at this scale and becomes the point.
Ten thousand rows and up
Cost becomes the binding constraint rather than time, and the highest-leverage change is no longer technical. Filtering before the expensive step routinely removes half the volume: run a cheap classifier or a firmographic filter first, then run the expensive generation only on rows that survive. Scoring for ICP fit before personalising is the usual version of this, and it improves the output as well as the bill, because a list that was worth filtering was a list with rows you should not have written to.
Keeping the sheet without the ceiling
Nothing above is an argument against spreadsheets. A sheet is an excellent interface for this work: everyone has one, the data is already there, and the result belongs next to the input.
The part that does not belong in the sheet is the execution. Once per-row work leaves the document, the cell caps and runtime walls stop applying and the real constraints become cost per row and honest failure handling.
That is how ReplyLabs is built: select the column in the sheet, the batch runs on our infrastructure with retries and concurrency, and results come back into the cells with a status per row. No 350-cell action cap, no 6-minute wall, and you are charged only for rows that succeed. The cost calculator will tell you what a given row count and model comes to before you run anything.