Translation Mixer.

June 7, 2026 · Updated September 26, 2026 · By Jeremy Lemley / Lemley Tech · 9 min read

Google Translate API Rate Limits Explained (and the "User Rate Limit Exceeded" Error)

behind the scenes
technology

If you landed here from a search, you probably just saw 403 User Rate Limit Exceeded or 429 Resource has been exhausted in your logs. The first half of this post is the practical fix. The second half is the story of how running a translation app taught us these limits the expensive way.


What "User Rate Limit Exceeded" Actually Means

The Google Cloud Translation API enforces several distinct quotas, and the error you get tells you which one you hit:

  • userRateLimitExceeded (HTTP 403) is the per-user short-window quota. This is a burst limiter. You sent too many characters too fast from one user context, even if your project-wide quota is fine. It's the most common error for apps that funnel all traffic through a single server IP or API key without distinguishing end users.
  • rateLimitExceeded / RESOURCE_EXHAUSTED (HTTP 429) means your project exceeded its per-minute character quota. All requests from your project are throttled until the window rolls over.
  • dailyLimitExceeded (HTTP 403) means you've burned the project's daily quota, or your billing cap. Nothing resets until midnight Pacific.

The critical thing all three have in common is that Google Translate quotas are measured in characters, not requests. A request translating "cat" and a request translating five paragraphs are wildly different against your quota, even though they're both one call. If you're rate-limiting or budgeting your own app by request count, your model is wrong. More on how we learned that below.

The Quota Tiers

The first 500,000 characters per month are free, applied as a billing credit. After that you pay roughly $20 per million characters, billed per character, including whitespace and including characters in requests that fail validation on your side after translation. Every character you send counts.

Each project also has a characters-per-minute ceiling and a per-user burst ceiling. Unlike the price, these are adjustable. Go to IAM & Admin, then Quotas in the Cloud Console, filter for the Translation API, and you can request increases or, just as usefully, lower them to cap your worst-case bill.

That last point is underrated. Quotas are a cost-control tool, not just an obstacle. Setting a deliberately modest per-minute cap means a runaway loop in your code fails with a 429 instead of a four-digit invoice.

How to Fix It

1. Retry with exponential backoff and jitter. Rate-limit errors are transient by design. The standard pattern:

import random, time

def translate_with_backoff(client, text, target, max_retries=5):
    for attempt in range(max_retries):
        try:
            return client.translate(text, target_language=target)
        except Exception as e:
            status = getattr(e, "code", None)
            if status not in (403, 429):
                raise                      # real error, don't retry
            if attempt == max_retries - 1:
                raise                      # out of retries
            # 1s, 2s, 4s, 8s... plus jitter so parallel workers don't sync up
            time.sleep(2 ** attempt + random.random())

The jitter matters. If twenty workers all hit the limit at once and all sleep exactly two seconds, they all come back at once and hit it again.

2. Batch your text. The API accepts multiple strings per request. One request with 50 short strings consumes the same character quota as 50 individual requests, but avoids per-request overhead and burst-limit trouble.

3. Cache aggressively. Translation output for identical input is deterministic enough to cache. If your app ever translates the same string twice, you're paying twice for one answer. A simple hash-keyed cache in front of the API is often the single biggest quota saver.

4. Track characters, not calls. Whatever internal limiter or budget alarm you have, denominate it in characters so it matches how Google actually bills and throttles. This is the one that bit us, and the failure mode is sneakier than it sounds.


How a Translation App Learned This the Hard Way

(Landed here from a limit message on the mixer? This half is for you: what the limit is, why it exists, and how to get translating again.)

When you paste a sentence into Translation Mixer and watch it tumble through six languages before landing back in English as something wonderfully weird, it looks effortless. Behind the scenes, each hop is a real Cloud Translation API call. Translating a phrase through seven languages isn't one operation. It's seven separate billed calls, and each call's cost scales with the character count of the text at that hop.

The $6 Wake-Up Call

Early on, Translation Mixer rate-limited users by counting API requests. The thinking was simple. Limit how many times someone can call the translate endpoint, and you limit costs.

Then one morning: an alert. Overnight, a user had submitted some very long text, multiple times. Each submission was only a handful of API calls, so the request-based limiter saw nothing unusual. But those calls contained a lot of characters, and the character-based billing statement told a different story.

The damage was about $6. Not catastrophic, but the same pattern with longer inputs, more concurrent users, or a bot hammering the endpoint could have generated hundreds of dollars overnight with no one awake to stop it. Six dollars is a cheap lesson. It's the exact per-request-versus-per-character mismatch described above, running in production, billing us instead of erroring.

The Fix: Counting Characters Instead

We threw out request-based limiting entirely. Now the system tracks the total characters you've submitted within a rolling window. Hit the ceiling and you'll see a limit message, not because you clicked too many times, but because you've consumed your share of translation capacity for that period. The limiter finally speaks the same language as the bill.

There are two things being counted, and they're easy to confuse. One is the size of a single mix, which is capped per submission. The other is your character allowance, which is the running total across everything you've sent in the current window. A single long paragraph can bump into the first. A morning of enthusiastic chaining will eventually bump into the second.

The allowance also explains something people find counterintuitive. A ten-language chain costs roughly twice what a five-language chain costs for the same input text, because the text gets translated ten times instead of five. Chain length is the fastest way to spend an allowance.

Signed-in accounts get a higher allowance than anonymous visitors, on a shorter window: eight hours rather than twelve. The gap exists because anonymous sessions are what bots use. A script can hammer an endpoint endlessly without creating an account, and tighter anonymous limits make that unprofitable while leaving plenty of room for real people playing with language chains. Signing in is free and immediately raises the ceiling.

⚠️ Specific limits and windows are subject to change. The message you see in the app always reflects current values.

Boosts and Memberships

There are also two paid tiers, which exist because the free ceilings have to be set for the median visitor and some people want considerably more room than that.

Espresso Boost is a one-off $3 purchase. It raises the size cap on a single mix to 3,000 characters, adds 50,000 characters to your allowance, and lasts thirty days. It suits someone with a specific long piece of text to run, or a week where they're using the mixer heavily and would rather not think about it.

Mixer Club is a $5 per month membership. It raises the single-mix cap to 5,000 characters, adds 150,000 to the allowance, extends chains from ten languages to fifteen, and removes the ads. It also exempts you from the temporary reductions described below.

One detail worth stating plainly, because the platform makes it easy to get wrong. Both tiers are specific items on our Buy Me a Coffee page, and buying one of those items is what grants the limits. A plain one-off coffee is a tip. Tips are lovely and genuinely appreciated, but they don't change any limits, because nothing on our end can tell a tip apart from any other tip. If you bought a Boost or a membership under a different email address than the one on your account, the claim page will link the two.

When traffic is unusually heavy we sometimes lower the per-mix cap for everyone on the free tiers for a while. It's a blunt instrument, it's temporary, and the app says so when it's active. Paid tiers keep their full caps through those stretches, which is the main practical reason we mention them here at all.

Why Rate Limits Exist on a Mostly Free Tool

Translation Mixer is free to use, and the great majority of people who use it never pay anything. But free to the user doesn't mean free to run. Every translation costs real money, fractions of a cent at a time, and at high volume with large inputs it adds up fast. The paid tiers cover a slice of that cost. Limits cover the rest.

Think of a free coffee station at a community event. It works because the organizers budgeted for reasonable use. If one person fills a thermos and walks off, there's nothing left for anyone else. Rate limits are the one-cup-per-person sign. Not stinginess, just how the coffee stays free.

If You Hit Our Limit

It's temporary. The window resets on its own, with no midnight wait. If it happens often, in rough order of how much they help:

  • Sign in. Free, and it raises the ceiling immediately.
  • Use fewer language hops. A four-language chain consumes well under half of what a ten-language chain does on the same text. This is usually the biggest saving available.
  • Break long text into shorter segments. A paragraph at a time rather than a full page.
  • Pick up a Boost or a membership if you've tried the above and still find the ceiling in your way.

The Bigger Picture

Every API-powered product rate-limits something: requests, tokens, characters, compute seconds. The specifics vary and the goal is the same, which is keeping the service sustainable for everyone. If you're building on the Translate API, the takeaway from our production experience is one sentence. Make your internal limits and alarms count the same unit Google bills, which is characters, and set your Cloud Console quotas low enough that bugs fail loudly instead of expensively.

If you enjoy Translation Mixer and want to help keep it running, there are a few ways. If you're learning a language, consider subscribing to one of our affiliate partners: LanguaTalk for live tutoring sessions, or LingoPie for learning through TV shows and movies. They're genuinely useful services, and a subscription through our links helps offset the API and server costs. A Boost or a membership does the same thing and gets you higher limits in return. And if you'd just like to drop a coffee in the tip jar with nothing expected back, that's always appreciated too.


Curious what all those API calls actually produce? Run a sentence through a language chain → and see. Or read The Same Sentence Costs Five Times More in Russian Than in Chinese, which measures what a chain costs language by language, How Translation Mixer Was Born and A Brief History of Machine Translation for more from behind the scenes.

Try it yourself →

Send your own sentence through the translation telephone game and see what comes back.