Gemini 429 RESOURCE_EXHAUSTED: rate limit or quota?
Google returns the same 429 for a per-minute limit and a spent daily quota. How to tell them apart, when the daily quota resets, and how to fail over.
{"error":{"code":429,"message":"Resource has been exhausted
(e.g. check quota).","status":"RESOURCE_EXHAUSTED"}}The parenthetical is doing a lot of work there. Google returns this same status for two situations that need opposite responses:
- A per-minute rate limit. Clears in under a minute. Retrying shortly is correct.
- A spent daily quota. Does not clear until the quota window rolls. Retrying is pointless for hours.
The message itself often does not distinguish them, which is why people end up retrying a dead account all afternoon.
How to tell which one you have
Check retryDelay in the error body. Google frequently includes it:
{"error":{"code":429,"details":[{"@type":"type.googleapis.com/google.rpc.RetryInfo",
"retryDelay":"41s"}]}}Seconds means rate limit. If the delay is in hours -- or the message says "resets in 4h" -- it is the daily quota, and no client-side retry strategy helps.
Check whether a different model works. Limits on the Gemini API are set per model. If Flash works while Pro is exhausted, you have a per-model quota, not an account-wide one.
Check the time of day. On the Gemini API, requests-per-day quotas reset at midnight Pacific time. If you are consistently blocked in your evening and fine the next morning, that is the signal.
Check that the model has a free tier at all. On a free-tier project, the Flash models (Gemini 3.5 to 3.8 Flash, and 3.5 Flash-Lite) are free of charge; Gemini 3.1 Pro Preview has no free tier. If every request to a Pro model fails from the very first call, look at your project's tier before you look at your traffic.
Failing over properly
The correct behaviour differs per case, and doing it by hand is tedious:
- Rate limit: back off briefly, then retry the same account.
- Daily quota: stop using that account entirely until the reset, and send the work somewhere else.
Treating the second case like the first is the expensive mistake. An exhausted account that gets retried every 30 minutes produces a stream of failures, and in an agent loop each one costs you a stalled task.
This is a case worth automating. A router that knows the real reset time can park the account until then rather than guessing, and route the request to another account or provider in the meantime:
npm install -g @sifxprime/krouter
krouter -tWhat kRouter does with a 429:
- When the provider names a reset time -- a
Retry-Afterheader on any provider, or Google'sretryDelayon its Antigravity and Gemini CLI connections -- kRouter honours it. A reset more than a minute away sends the request to the next account instead of retrying, and an exhausted model is parked on that account until its reset (six hours at most). Other models on the same account stay usable. - When it does not, the account cools down with exponential backoff, from 2 seconds up to 5 minutes, and the request moves on.
Two details matter if you add more Gemini API keys. Limits apply per project, not per key, so a second key in the same project adds nothing. And when no account is left, a combo moves on to its next model, so the last resort can be a different provider entirely.
What does not work
Retrying immediately in a loop. A per-minute window does not clear faster because you keep asking, and against a spent daily quota every retry is a guaranteed failure.
Creating another API key on the same project. Quota is enforced per project, not per key.
Switching endpoints. On the Gemini API the limits belong to the project, so the same key sent to a different endpoint draws on the same quota.
Shrinking the prompt. If the limit is on requests per minute, token count is irrelevant. Check retryDelay before optimising the wrong thing.
A note on free-tier Gemini
The free tier has a lower per-minute ceiling than paid. If you are hitting 429s within seconds of starting an agent run, that is expected rather than a misconfiguration -- an agent sends many more requests per minute than a chat session, and the free ceiling was not sized for it.
Routing agent traffic to a provider with a higher ceiling and keeping free Gemini for one-shot work resolves this without paying.
One case is not a quota problem at all. If this comes from Gemini CLI signed in with a personal Google account, note that Google stopped serving Gemini CLI to free users and to Google AI Pro and Ultra subscribers on June 18, 2026 (what still works).
Common questions
Is RESOURCE_EXHAUSTED a rate limit or a quota problem?
It is both, depending on the case, which is why it is so often misread. Check retryDelay in the error body: a delay in seconds means a per-minute rate limit, and a delay in hours means the daily quota. Google returns the same status for each.
How long until Gemini quota resets?
On the Gemini API, requests-per-day quotas reset at midnight Pacific time. Per-minute limits clear within a minute. If you are consistently blocked during your evening, the daily quota is the likely cause.
Will a new API key restore my quota?
No. Quota is enforced per project, not per key. A second key on the same project shares the same allowance.
Does switching region help?
Not on the Gemini API: its limits are applied per project, and there is no regional quota to move to. Vertex AI is a separate product with its own quota system.
Why does the free tier 429 within seconds of starting an agent?
The free tier's per-minute ceiling is lower than paid, and an agent sends many more requests per minute than a chat session. That is expected behaviour rather than a misconfiguration.
Related
Published by Kodelyth, the team that builds kRouter. Posts are drafted with AI assistance and reviewed by a person before they go out. kRouter is free and MIT licensed.
Install kRouterRelated posts
- Fix an errorClaude Code "rate limit exceeded": every cause and the fixClaude Code stops with a 429 or a usage limit. Four different limits cause it, each needs a different fix, and the one everyone tries first makes it worse.
- Fix an errorClaude Code weekly limit reached: keep working until resetClaude Code says you've hit your weekly limit. What the caps count, what does not help, and three ways to keep working until the reset.
- Fix an errorCodex usage limit reached: keep working until it resetsCodex says you've hit your usage limit. What the five-hour and weekly caps count, when the message is wrong, and how to keep working until the reset.
Relevant docs
- TroubleshootingFixes for common kRouter problems: banned or rate-limited accounts, OAuth sign-ins, MITM certificates, localhost and Cursor, Docker logins and the CLI.
- Error referenceWhat the common AI provider errors mean, why they happen, and how to get past them.
- Combos & fallbackPut several models behind one name. kRouter falls back from one to the next, rotates them, or asks a panel of models and merges the answers.