Gemini 429 RESOURCE_EXHAUSTED: Causes and How to Fix It

Quick Fix

Seeing 429 RESOURCE_EXHAUSTED from the Gemini API? Check these in order:

  • Are you on the free tier? Free limits are tight and include a per-day (RPD) cap — enabling billing raises all of them dramatically.
  • Which quota did you hit — per minute or per day? A per-day cap won’t clear by waiting a few seconds; it resets at midnight Pacific.
  • Add backoff + jitter for the per-minute case, and consider a smaller/faster model (e.g. Flash) with higher headroom.

Google Gemini returns HTTP 429 with status RESOURCE_EXHAUSTED when you exceed a quota. The twist that catches developers out: Gemini enforces requests per minute (RPM), tokens per minute (TPM), and requests per day (RPD). Backoff handles the per-minute limits, but a per-day cap is a different beast — it won’t clear no matter how long you retry within the day.

What this error means

Gemini 429 RESOURCE_EXHAUSTED
{
"error": {
  "code": 429,
  "message": "Resource has been exhausted (e.g. check quota).",
  "status": "RESOURCE_EXHAUSTED"
}
}

There are three quota dimensions, and any one of them returns the same 429:

Gemini quota dimensions — any one hitting zero triggers RESOURCE_EXHAUSTED.
QuotaWindowClears by waiting?
RPM — requests per minute Rolling minuteYes — seconds
TPM — tokens per minute Rolling minuteYes — seconds
RPD — requests per day Per calendar day (PT)No — resets at midnight Pacific

Common causes

  • Free-tier limits. The free tier has low RPM and a hard daily request cap. Hobby projects hit the RPD ceiling and assume the API is broken.
  • The per-day cap (RPD). You sail through the morning, then every request 429s by afternoon. Backoff won’t help — you’re out of daily quota.
  • Bursty concurrency exceeding RPM in a single window.
  • Large prompts burning TPM (long context, files, images).
  • Per-model quotas. Limits are tracked per model; a heavily-used model can be exhausted while another has room.

How to fix it

Enable billing — the biggest single lever

Moving a project from the free tier to pay-as-you-go raises RPM/TPM/RPD by orders of magnitude. If you’re building anything beyond a toy, set up billing in Google AI Studio / Cloud Console first — it resolves most RESOURCE_EXHAUSTED errors outright.

Back off and retry (per-minute quotas)

Python — google-genai with backoff
from google import genai
from google.genai import errors
import time, random

client = genai.Client()  # reads GEMINI_API_KEY from env

def generate_with_backoff(prompt, model="gemini-2.5-flash", max_attempts=6):
  for attempt in range(max_attempts):
      try:
          return client.models.generate_content(model=model, contents=prompt)
      except errors.APIError as e:
          if e.code != 429 or attempt == max_attempts - 1:
              raise
          time.sleep((2 ** attempt) + random.random())

resp = generate_with_backoff("Hello")
print(resp.text)
JavaScript / Node — @google/genai with backoff
import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({}); // reads GEMINI_API_KEY from env
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function generateWithBackoff(prompt, model = "gemini-2.5-flash", maxAttempts = 6) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
  try {
    return await ai.models.generateContent({ model, contents: prompt });
  } catch (err) {
    const status = err?.status ?? err?.code;
    if (status !== 429 || attempt === maxAttempts - 1) throw err;
    await sleep(2 ** attempt * 1000 + Math.random() * 1000);
  }
}
}

const resp = await generateWithBackoff("Hello");
console.log(resp.text);
cURL — retry on 429
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
--retry 5 --retry-all-errors --retry-max-time 60 \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contents":[{"parts":[{"text":"Hello"}]}]}'

If it’s the daily cap (RPD)

Backoff won’t save you — the quota resets at midnight Pacific. Your options:

  • Enable billing to raise (or remove) the daily cap.
  • Request a quota increase in the Cloud Console (IAM & Admin → Quotas) for the specific model/limit.
  • Switch to a model with higher quota — Flash-class models generally have far more headroom than Pro.
  • Spread work across the day if you must stay on free-tier limits.

Check your real quotas

Don’t guess your ceilings — view them in Google AI Studio (per API key) or the Cloud Console Quotas page, filtered to the Generative Language API and your model. See the rate limits reference for how provider tiers scale.

How to prevent it

  • Run on a billed project for anything production — free-tier caps are for prototyping.
  • Throttle batch work behind a limiter under your RPM/TPM.
  • Route tolerant tasks to Flash to preserve Pro quota.
  • Track usage against the daily cap and alert before you hit it, since it won’t self-heal mid-day.
Watch out

Retrying a per-day (RPD) exhaustion in a tight loop just burns CPU and logs noise — the quota is gone until the daily reset. Detect a sustained 429 and stop, rather than hammering until midnight.

Headroom across providers

If Gemini’s free-tier or daily caps keep blocking you, routing across providers buys headroom without rewriting SDK code. OpenRouter exposes Gemini and other models through one OpenAI-compatible API with failover. (Affiliate link.)

What to do next

  1. Determine whether you hit a per-minute or per-day quota — they need different fixes.
  2. Enable billing to lift free-tier ceilings, the highest-impact change.
  3. Add capped backoff with jitter for per-minute limits.
  4. Request a quota increase or switch to a Flash model if you’re still constrained.

Frequently asked questions

Does RESOURCE_EXHAUSTED always mean rate limiting?
It means you exhausted a quota, which could be per-minute (RPM/TPM) or per-day (RPD). Per-minute quotas clear in seconds with backoff; a per-day quota does not clear until the daily reset at midnight Pacific. Identify which one before deciding to retry.
Why did Gemini work this morning but 429 all afternoon?
You almost certainly hit the requests-per-day (RPD) cap on the free tier. It won't recover by retrying — enable billing, request a higher quota, or switch to a higher-quota model.
How do I raise my Gemini rate limits?
Enable billing to move off the free tier (the biggest jump), then request a quota increase for the specific model and limit in the Cloud Console under IAM & Admin → Quotas. Flash-class models also carry much higher quotas than Pro.
Will switching to Gemini Flash stop the 429s?
Often, yes — Flash models generally have higher RPM/TPM/RPD than Pro models, so routing tolerant tasks to Flash relieves pressure. It won't help if your whole project is over a shared daily cap; for that, enable billing or raise the quota.
What's the best backoff strategy for Gemini?
Exponential backoff with jitter (~1s, 2s, 4s, 8s plus randomness), capped at a few attempts, for per-minute quotas. For a per-day exhaustion, stop retrying and alert — the quota is unavailable until the daily reset.