Google Sheets Quota Exceeded: Why a Spreadsheet Makes an Unstable Database
Back to blog
automation·September 5, 2026·4 min read·By Yehonatan Saadia

Google Sheets Quota Exceeded: Why a Spreadsheet Makes an Unstable Database

The Sheets API allows 300 requests per minute per project and 60 per minute per user, for reads and writes separately. Why automations cross it, and the fix.

Key takeaways

  • The documented quotas: 300 requests per minute per project and 60 per minute per user per project, counted separately for reads and writes.
  • Exceeding them returns 429, and the official guidance is exponential backoff. After one minute you can execute requests again.
  • The per-user quota is what breaks first, because your automations usually all run under one service account.
  • One request writing 500 rows and one request writing a single row cost exactly the same against the quota. That is the whole story.
  • A perfectly valid request also fails if it runs longer than 180 seconds. That is a separate limit from the quota.

Google publishes explicit quotas for the Sheets API: 300 read requests per minute per project and 60 per minute per user per project, with the identical numbers applying separately to writes. Exceeding them returns a 429: Too many requests. Automations cross that line because they write one row at a time instead of batching.

The numbers, and which one actually stops you

QuotaValueWhat it is counted against
Read requests per minute300Per project
Read requests per minute per user60Per user per project
Write requests per minute300Per project
Write requests per minute per user60Per user per project
Maximum request duration180 secondsPer single request

Rows two and four are the painful ones. Sixty requests per minute per user means roughly one request per second on average. A job that loops over 400 rows and updates each one separately blows through it in about a minute - even if nothing else is running.

Note what is not in the table: there is no daily aggregate limit. As long as you stay inside the per-minute quotas, nothing further caps you later in the day.

Why does a spreadsheet that worked for a year start failing now?

Because the quota counts request rate, not data volume, so three innocent-looking changes cross it without anyone touching the code:

  • A second automation appeared. Two scenarios running under the same service account share that user's 60-per-minute budget; they do not each get one.
  • The row count grew. A loop over 50 rows makes 50 requests; the same loop over 300 rows makes 300, and identical code starts failing.
  • The trigger got more frequent. Moving from hourly to every five minutes multiplies consumption twelvefold with no change in logic at all.

The tell is that the failure is not consistent. Some rows write and some do not, and the next run succeeds. A spreadsheet that fails consistently is usually a permissions problem; one that fails partially and unpredictably is almost always quota.

The three mistakes that multiply request count

  1. Reading inside a loop. Fetching a value per row instead of reading the whole range once. Three hundred rows become three hundred read requests.
  2. Writing row by row. Updating one cell at a time, usually because the automation is built inside a "for each item" loop.
  3. Re-reading the same static data. Fetching the same header row or settings range on every iteration instead of once at the start of the run.

All three come from the same assumption: that a spreadsheet is a database you can send small queries to whenever you like. The Sheets API is not built that way - it is built around ranges.

Cutting request count without leaving the spreadsheet

  • Read the whole range once into memory, do the work in memory, and write back once. This is the single highest-return change.
  • Batch several ranges into one request instead of issuing a separate request per range.
  • Append new rows as one group at the end of the run, not on every iteration.
  • Split automations across different projects or users so they are not sharing one per-minute budget.
  • Store fixed configuration values inside the automation rather than in a tab that gets read every cycle.
  • Sync only what changed since the last timestamp rather than the whole sheet.
  • Do not split one huge request into a thousand tiny ones to avoid the timeout. That trades a duration limit for a quota limit.

What correct backoff after a 429 looks like

Google's documentation does not leave this to interpretation: on exceeding the quota you should use an exponential backoff algorithm, with the wait between retries computed as the smaller of a maximum backoff and two raised to the attempt number plus a random number of milliseconds. The random component is not decoration - without it every process that failed together retries in the same millisecond and knocks itself over again.

  • Set a maximum backoff and stop retrying at some point rather than looping forever.
  • Add jitter to every delay.
  • Count retries per run. A rise in that number is the early warning that arrives before the job starts losing data.

When is the spreadsheet the wrong tool?

When quota errors return after you have already batched. If a run now performs one read and one write and still stalls, the problem is not the code - it is that the spreadsheet is being used as an operational database. Other signs pointing at the same conclusion: more than one person editing simultaneously, formulas recalculating on every load, and tabs that exist only to hold a process's state.

The answer is not necessarily a full migration. Usually it is enough to move the write layer into a database and leave the spreadsheet as a view refreshed on a fixed interval - one read instead of hundreds.

Confirming it really is quota and not something else

Three different problems produce the identical feeling of "the sheet is not updating", and separating them takes only a few minutes:

  • Quota. The failure is partial and inconsistent, appears at peak activity, and the status code is 429. Rerunning a minute later succeeds.
  • Permissions. The failure is perfectly consistent and appears on every run, including a manual one. A change to file sharing or to the service account's access is the immediate suspect.
  • The duration limit. The request itself is too large and runs past 180 seconds. Slowing down will not help here, and splitting into smaller requests is the fix - the exact opposite of the fix for quota.

It is also worth separating the layers: a job running through Apps Script is measured against its own quota system, distinct from the Sheets API quota of a Google Cloud project. A process that fails through one layer and works through the other is telling you the limit that broke is not the one you assumed.

  • Log the full status code, not only the message your tool shows you.
  • Measure how many requests actually went out per minute, not how many rows were processed.
  • Run the same operation by hand when nothing else is running. If it passes, it was quota.

Related: How to automate Google Sheets, Architecture for a 50,000-row sheet, Connecting Google Sheets to your other tools.

Sources

#Google Sheets#API quotas#automation#429 error#spreadsheets#Make

Frequently asked questions

What exactly is the Google Sheets API quota?

Google documents 300 read requests per minute per project and 60 read requests per minute per user per project, with the same values applying separately to write requests. There is no daily aggregate limit as long as you stay inside the per-minute quotas.

How long should I wait after a quota error?

Google's documentation states that after one minute you can execute requests again, but the correct approach is exponential backoff with a random component rather than a fixed wait. A fixed wait makes every failed process retry together and fail together at the same moment.

Does writing 1,000 rows cost more than writing one?

Not in quota terms. The quota counts requests, not rows, so one request writing 1,000 rows is equivalent to one request writing a single row. That is exactly why batching is the most effective fix for a quota error.

Will a separate service account solve it?

It can help, because the 60-per-minute quota is counted per user per project, and separating automations across users stops them sharing one budget. It does not fix code that makes hundreds of unnecessary requests - it only raises the ceiling they eventually hit.

Keep reading

Related service

Integrations

Make the systems you already pay for talk to each other.

Learn more →←

About the author

Yehonatan Saadia

Freelance automation, web & MVP developer

I'm Yehonatan Saadia, a senior developer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.

Work with me

Have a project like this?

Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.