Fix AWS API Gateway 429 Throttled: Account-Level vs Stage-Level Rate Limits Explained

Logeshwaran.C

If API Gateway is handing you 429 Too Many Requests, it isn't automatically your fault, and it isn't automatically your traffic. That one status code can come from four separate throttling settings stacked on top of each other, and the one almost nobody checks first — a single request-rate bucket shared by every API in your AWS account, in that Region — gets applied before your usage plan is even consulted. Which means the exact same code, calling the exact same endpoint, can pass on Tuesday and get throttled on Wednesday without you changing a single line, because some other API in the same account had a busy morning. In our last post, we had seen API Gateway: CORS works in Postman but not the browser so let's continue the error series and fixes.

⚡ Quick Answer

Check which limit you're hitting first → look at your API Gateway account-level throttle settings, then your stage/method settings, then your usage plan, in that order.

Default account limit → 10,000 requests per second, burst 5,000 (lower in some Regions — see the table below).

Most common fix → a per-method throttling target on the noisy API/stage, not a blanket account-level increase.

If you only read this box: don't request an account-wide increase before you know which of the four layers actually threw the 429 — jump to the diagnostic first.

Jake found this out the expensive way. A customer's repair-tracking app — built on top of a small REST API his shop uses to look up phone parts — started throwing errors during a Saturday rush. Nothing had changed in his code. Nothing had changed in his traffic, either; if anything it was a normal Saturday. But requests that had worked all week were suddenly bouncing back with a 429, and Jake, not being an AWS person, assumed the API itself was broken.

It wasn't broken. It was throttled — and figuring out which of the four throttling settings did it turned out to matter more than anything else in fixing it. That's what this post walks through: what each layer actually limits, in what order API Gateway checks them, the exact numbers AWS documents for each one, how to find out which one is biting you, and what to do about each — including the cases where the honest answer is "don't touch the limit, fix the traffic instead."

What a 429 from API Gateway is actually telling you

API Gateway throttles requests using something called a token bucket algorithm. Think of it like a bucket that refills with tokens at a steady rate — say, ten thousand tokens dropped in every second. Every request that arrives spends one token. As long as tokens keep coming in faster than you're spending them, everything sails through. But the bucket also has a maximum size, called the burst limit: if you suddenly fire off a thousand requests in the same instant, you can spend more tokens than the steady rate would normally allow, up to the size of the bucket, before you run dry. Once the bucket is empty, the next request gets a 429 until it refills a little.

Both throttles and quotas are applied on a best-effort basis — AWS is explicit that these are targets, not guaranteed ceilings. That matters because it explains why two identical-looking traffic bursts can sometimes behave slightly differently; the token bucket isn't a perfectly rigid wall, it's a very consistent approximation of one.

‍♂️ Jake's Reality Check

"So it's not that my API is 'too slow' or 'broken' — it's that a bucket somewhere ran out of tokens?"

Pretty much. A 429 means API Gateway made a deliberate decision to reject the request because a rate limit was hit — it's not a crash, a timeout, or a bug in your backend. The backend never even saw the request. That's actually good news: it means the fix is a settings problem, not a code problem.

The four throttling layers, and the order AWS checks them

This is the part almost every "just increase the limit" answer online skips, and it's the part that actually determines what you should click. API Gateway documents four distinct types of throttling-related settings, and they don't compete equally — they're evaluated in a specific, narrowest-first order:

  1. Per-client or per-method throttling limits set for an API stage inside a usage plan — the tightest, most specific rule, checked first.
  2. Per-method throttling limits set directly on an API stage (outside a usage plan).
  3. Account-level throttling for the Region — the shared bucket across every API you own there.
  4. AWS Regional throttling — the outer ceiling AWS sets for the whole Region, across every customer.

Here's the practical reading of that order, and it's the single most useful sentence in this post: a tighter setting protects everything above it, but nothing protects it from everything below it running out first. If you set a generous per-method target of 2,000 RPS on your API, but your account-level bucket for the Region is capped at 2,500 RPS and three other APIs in the same account are already using 2,000 of it, your "generous" 2,000 RPS setting is meaningless — the account bucket empties before your method-level allowance ever gets exercised.

Layer Scope Who sets it Can you request an increase?
AWS Regional Every account and client in the Region AWS No — not customer-controlled at all
Account-level, per Region All your APIs (REST, HTTP, WebSocket) in that Region You (rate only) Yes, rate — burst is not adjustable
Stage / method-level One method, or all methods on one stage You You set it directly, capped by the account limit
Per-client (usage plan) One API key / one client You You set it directly, capped by the account limit

Ethan puts it more bluntly when Jake asks why the numbers don't just "stack up" the way he expects. "You're not choosing the biggest bucket you're allowed," Ethan says. "You're choosing the smallest one you've set, and hoping nothing upstream of it runs dry first. Most people configure the tightest layer carefully and forget the account layer even exists — until a Saturday rush proves it does."

Diagnose which layer is actually throttling you

Before you touch any setting, work out which layer produced the 429 you're looking at. Guessing wrong wastes a support ticket and doesn't fix anything, because raising the account limit does nothing if a stage-level method throttle was the actual cause, and vice versa.

  1. Turn on CloudWatch Logs for the stage, at the ERROR log level. This generates execution logs only for requests that fail — including throttled ones — without drowning you in log volume from healthy traffic. Do this in the stage's Logs/Tracing settings.
  2. Reproduce the 429, then read the execution log entry for it. A request rejected for exceeding a usage-plan or API-key throttle records that reason explicitly in the log. A request rejected because the shared account bucket ran dry generally will not carry that same per-key message — it fails silently at the account layer, which is itself a clue.
  3. Check whether a usage plan is even attached to the stage. If the caller isn't presenting an API key associated with a usage plan, per-client throttling never enters the picture at all — you can immediately rule out layer one.
  4. Open the stage's throttling settings in the console and note whatever rate and burst values are configured there. If they're set noticeably lower than 10,000/5,000 (or than whatever your account-level numbers are), that stage-level setting is very likely your ceiling.
  5. Check the account-level throttle settings for the Region against the default table further down this post. If your account shows a number lower than you expected for your Region, and nothing else explains the 429, this is your layer.
  6. Ask whether anything else in the same account and Region shares this bucket. A second API, a different team's Lambda-backed endpoint, even a load test someone forgot was still running — all of it draws from the same account-level bucket. This is the layer people skip checking, and it's the one behind the "nothing changed, but we're getting throttled" reports more than any other.

✅ Why this is the one to check first

The account-level bucket is invisible from inside any single API's dashboard — you have to go looking for it deliberately. Everything else (stage settings, usage plan settings) is visible right where you'd naturally look, which is exactly why it gets checked and the shared bucket doesn't. Make it step one, not step five.

Account-level throttling per Region — the bucket everyone shares

By default, API Gateway limits the steady-state requests-per-second rate across all APIs within an AWS account, per Region — and that "all" includes REST APIs, HTTP APIs, WebSocket APIs, and WebSocket callback APIs together, sharing one bucket. It also limits burst, the maximum size of that token bucket, which represents the target maximum number of concurrent request submissions API Gateway will fulfill before it starts returning 429s.

The default numbers, for most Regions, are:

Region group Default steady-state rate Default burst
Most Regions (US East, US West, EU Ireland, etc.) 10,000 RPS 5,000
Africa (Cape Town), Europe (Milan), Europe (Spain), Europe (Zurich), Asia Pacific (Jakarta), Asia Pacific (Hyderabad), Asia Pacific (Melbourne), Asia Pacific (Malaysia), Asia Pacific (Thailand), Middle East (UAE), Israel (Tel Aviv), Canada West (Calgary), Mexico (Central) 2,500 RPS 1,250

If your account lives in one of those newer or smaller Regions, don't assume the "standard" 10,000 figure applies to you — it doesn't, by design, and no amount of stage-level tuning changes that underlying ceiling. This is exactly the discrepancy that trips people up when they compare what the Service Quotas console shows against what the API Gateway console's throttling settings actually display for a specific account; the two can legitimately disagree depending on how quota increases have been applied versus the Regional default.

One quirk worth knowing before you go chasing it: the burst quota is determined by AWS's service team based on your account's overall rate quota for that Region — it is explicitly not a number you can request a change to on its own. If you request more rate, AWS decides the accompanying burst; you don't set burst independently.

⚠️ What this actually breaks

Because this limit is shared across every API in the account and Region, a completely unrelated project — someone's internal admin tool, a batch job hitting an API Gateway-fronted Lambda in a loop, a load test left running overnight — can silently eat into the same bucket your production traffic depends on. There's no per-API carve-out unless you explicitly configure stage or method-level throttling to protect it.

Stage and method-level throttling

One step down from the account bucket, you can set per-API, per-stage throttling limits at the method level — applied to a single stage, either uniformly across every method or configured differently method by method (for example, GET /pets can have a different target than POST /pets). Because these limits can't be set higher than the account-level (and, beneath that, the AWS Regional) limit, they're purely a way to carve out and protect a smaller slice of the shared bucket — not a way to get more capacity than the account allows.

If you haven't explicitly configured a stage or method-level target, there's nothing standing between an individual method and the full account-level bucket — meaning a single busy endpoint can, on its own, consume the entire account's allowance and starve every other API you run in that Region. This is precisely why stage-level throttling exists as a separate, configurable layer: it lets you say "this endpoint may use up to X of our shared Y," so one loud method can't quietly spend the whole account.

How stage throttling is configured

You set stage-level throttling targets through the AWS Management Console, the AWS CLI (the create-stage and related update commands), or an SDK. In the console, this lives in the stage's settings. Method-level targets specifically inside a usage plan use a Resource=<resource>,Method=<method> notation — for example, Resource=/pets,Method=GET — to point the throttling target at one exact route rather than the whole stage.

There's a hard ceiling on how granular you can get here, too: a usage plan supports a default of 20 method-level throttling settings per stage. That's a small number if you have a large API surface and want per-route control everywhere. It can be increased by contacting AWS Support Center, but it isn't unlimited by default — plan your most important routes first if you're working within that ceiling.

Usage plans and per-client throttling

A usage plan is how you throttle individual callers rather than the API as a whole. Each usage plan is tied to one or more API keys, and each key gets its own token bucket — separate from every other key's bucket. This is the layer that stops one customer, or one integration partner, from being able to exhaust the API for everyone else, and it's checked first, before stage-level and account-level limits, precisely because it's the narrowest and most specific rule in play.

The catch, and it's a common source of confusion in the AWS forums: per-client limits set inside a usage plan can't be set higher than your per-account limits. If your account-level rate is stuck at 2,500 RPS because your Region defaults to that figure, giving a single client a usage-plan allowance of 5,000 RPS doesn't get honored — the account ceiling still applies underneath it. A usage plan divides up your existing bucket among clients; it doesn't create a bigger bucket.

‍♂️ Jake's Reality Check

"So if I give my three biggest customers each a 1,000 RPS usage plan, I've got 3,000 RPS of promises out — even though my account is only good for 2,500?"

Yes, and that's a real trap. Nothing stops you configuring usage plans whose numbers add up past your account limit — API Gateway won't warn you at setup time. The account bucket is what actually gets enforced when all three customers happen to be busy at once, and whichever request arrives when the shared bucket is empty gets the 429, usage plan promise or not.

Fixing account-level throttling

If your diagnosis in the earlier section points to the account layer, here's the actual path, straight from AWS's own steps for managing this quota:

  1. Open the Service Quotas console.
  2. In the navigation pane, choose AWS services.
  3. In the AWS services search bar, enter Amazon API Gateway.
  4. In the service quotas search bar, enter Throttle rate.
  5. Choose Request increase at account level.
  6. For Increase quota value, enter a value greater than 10,000 (or greater than whatever your current Regional default is).

Two things to know before you submit that request. First, the throttle burst rate quota is not adjustable — you can't request a burst increase on its own, and the request form won't offer one; burst follows automatically from whatever rate AWS approves. Second, an increase can't be granted above the AWS Regional throttling ceiling — there is a hard outer limit that no request, however well justified, moves past.

There's also a side effect worth planning for if you're pushing integration timeouts long: raising the integration timeout on a REST API beyond the default 29-second cap (the maximum you can request goes up from there for Regional and private REST APIs) can require a corresponding reduction in your account-level throttle quota. AWS trades one for the other — longer-running integrations, at scale, are more expensive to hold open, so the platform asks you to give something back on the rate side.

✅ Why this is the one to use — but only after diagnosis

An account-level increase is the right fix exactly when the diagnostic points there: several healthy APIs genuinely need more combined throughput than the Regional default allows. It's the wrong fix when one noisy method is the actual cause — in that case a stage-level throttle on the noisy method protects everyone else without needing AWS's approval on anything.

Fixing stage and method-level limits

If the diagnosis points here instead — one method or one stage is consuming a disproportionate share of the account bucket — the fix doesn't need a support ticket at all. You configure it yourself:

  1. Open the API in the console and go to the stage you want to protect.
  2. In the stage's settings, find the default method throttling controls and set a rate and burst that reflect what this stage should realistically be allowed to use out of your total account bucket.
  3. If different methods on the same stage need different treatment (a cheap read endpoint versus an expensive write endpoint, say), configure a usage plan with per-method targets using the Resource=...,Method=... format instead of one flat stage-wide number.
  4. Remember the ceiling: whatever you set here cannot exceed your account-level limit, and by extension cannot exceed the AWS Regional limit either. You're carving a slice, not adding capacity.

Ethan's take on this, when Jake asked why he'd bother setting a lower number on purpose: "Because it's the only lever you actually control without asking AWS for anything. Every other route in this post either requires a support ticket or a hard architectural change. This one, you can do in the console in five minutes, and it protects every other API in the account from whatever this one does next."

The noisy-neighbor problem inside one account

This is the scenario the diagnostic in this post is really built to catch, because it's the one that produces the most confusing symptoms. Say you're running two APIs in the same account and Region: a low-volume, expensive-per-call route that talks to a machine learning model, and a high-volume, cheap-per-call route that just reads from a cache. The expensive route is well within any limit you'd set for it directly. The cheap route, being cheap, gets hammered constantly and never trips its own generous stage-level allowance.

But both routes draw from the same account-level bucket. If the cheap route's traffic spikes — a retry storm, a misconfigured polling interval on someone's client, a cron job someone forgot to rate-limit — it can exhaust the shared account bucket entirely. The expensive route then starts returning 429s despite nothing about its own configuration, traffic, or code having changed at all. This is the exact mechanism behind the counterintuitive reveal at the top of this post, and it's genuinely one of the harder API Gateway problems to diagnose from inside a single API's own dashboard, because that dashboard has no visibility into what else is drawing from the same bucket.

The fix isn't on the quiet, expensive route — there's nothing wrong with it. The fix is a per-method throttle on the noisy, cheap route, sized to what it actually needs rather than left to help itself to the whole account bucket by default.

Watching for it: CloudWatch and execution logs

The 4XXError CloudWatch metric, tracked per API and per stage, is where a throttling spike will first show up numerically — it captures client-side errors including 429s. AWS's own recommended alarm on this metric uses an average statistic with a suggested threshold around 5% of total requests, evaluated over five one-minute periods, which is a reasonable starting point to tune from rather than a rule to follow blindly; your acceptable baseline error rate depends entirely on your own traffic pattern.

A rising 4XXError count alone doesn't tell you which of the four layers caused it, though — for that you need the execution logs. Turning on CloudWatch Logs at the ERROR log level for the stage means API Gateway only writes log entries for failing requests, which keeps the volume manageable while still catching every throttle event. When a request is rejected specifically for exceeding a usage plan's per-key allowance, that reason shows up explicitly in the log entry, which is your clearest possible signal that layer one — not the account bucket — is the cause.

Edge cases: HTTP APIs, WebSocket APIs, and private APIs

Everything above focuses on REST APIs, since that's where most of the throttling questions come from, but a few things change shape depending on the API type you're running.

HTTP APIs

The account-level throttle quota is explicitly shared across HTTP APIs, REST APIs, WebSocket APIs, and WebSocket callback APIs in the same account and Region. If you're running a mix of REST and HTTP APIs side by side, they are not throttled independently at the account layer — they're pulling from one combined bucket, which makes the noisy-neighbor scenario above just as relevant across API types as it is within one.

WebSocket APIs

WebSocket APIs support route-level throttling, which lets you override the account-level request throttling limits for a specific stage or for individual routes — but the ceiling still applies the same way: default route throttling limits can't exceed the account-level rate limits. Route-level throttling for WebSocket APIs is configured through the AWS CLI rather than fully through the console.

Private APIs and API Gateway portals

Private REST APIs draw on the same account and Regional pool as public ones — there's no separate, higher bucket just because an API sits behind a VPC endpoint. Separately, API Gateway's portal feature (for publishing API documentation and letting developers self-serve API keys) has its own distinct quotas: 250,000 requests per second without access control, and 10,000 RPS with access control, neither of which is customer-adjustable. These are unrelated to the throttling settings covered above and won't help or hurt your main API's limits either way.

When raising the limit is the wrong fix

Here's the part that's uncomfortable to say plainly, but needs saying: for a lot of teams hitting 429s, the correct fix isn't raising any limit at all. If your traffic pattern is bursty because clients retry immediately on failure — no delay, no backoff — you can create a self-reinforcing spike where the 429 itself causes more requests, which causes more 429s. AWS's own guidance for handling a 429 is that the client, upon catching the exception, should resubmit the failed request in a way that is itself rate-limited — not simply retry instantly.

Practically, that means:

  • Exponential backoff with jitter on the client side, so retries spread out over time instead of arriving in another synchronized burst.
  • Caching on read-heavy routes so repeated identical requests never reach API Gateway's token bucket at all.
  • Batching where your API design allows it, so ten small requests become one larger one.
  • Queueing in front of the API for write-heavy workloads that don't need synchronous responses, smoothing bursts into a steady rate the bucket can absorb.

None of that requires a support ticket, a quota increase, or waiting on AWS. And unlike an account-level increase, it actually reduces the chance of hitting the AWS Regional ceiling too — the one layer nobody can request more of, no matter how good the justification.

Frequently asked questions

What's the difference between account-level and stage-level throttling in API Gateway?

Account-level throttling is one shared bucket covering every API you run in an AWS account, in one Region. Stage-level (and method-level) throttling is a smaller allowance you configure yourself for one specific stage or route, and it can never be set higher than the account-level number underneath it — it only carves out and protects a slice of the shared bucket, it doesn't add to it.

Why do I get 429 errors even though I'm nowhere near 10,000 requests per second?

Two common reasons. First, your account may be in a Region where the default is 2,500 RPS rather than 10,000 — check your actual console settings rather than assuming the higher default. Second, the 10,000 RPS bucket is shared across every API in the account and Region, so a different, unrelated API drawing from the same bucket can leave far less headroom than you'd expect for yours.

Can I increase the API Gateway burst limit?

Not directly. The burst quota is determined by AWS's service team based on the overall RPS quota approved for your account in that Region — it isn't a value you can request a change to on its own. If you get a higher rate quota approved, AWS sets an accompanying burst figure for you.

How do I request an API Gateway throttling limit increase?

Through the Service Quotas console: choose AWS services, search for Amazon API Gateway, search the service's quotas for "Throttle rate," and choose Request increase at account level. Enter a value greater than your current quota. The request applies to the rate only, not the burst.

Does stage-level throttling override account-level throttling?

No — it works underneath it, not instead of it. A stage-level or method-level setting is checked before the account-level bucket in AWS's evaluation order, but it can never be configured to exceed the account limit. It restricts a slice of the shared bucket for one stage or method; it doesn't let that stage or method bypass the account ceiling.

What is a usage plan, and do I need one to stop 429 errors?

A usage plan lets you assign separate rate and burst allowances to individual clients identified by their API key, so one client can't consume the whole API's capacity. You don't strictly need one to stop 429s in general — stage-level throttling alone protects the API overall — but if the problem is one specific customer or integration overwhelming everyone else, a usage plan is the tool built for exactly that.

Why is my account-level throttle limit only 2,500 RPS instead of 10,000?

Some Regions — including Africa (Cape Town), Europe (Milan, Spain, Zurich), Asia Pacific (Jakarta, Hyderabad, Melbourne, Malaysia, Thailand), Middle East (UAE), Israel (Tel Aviv), Canada West (Calgary), and Mexico (Central) — carry a lower default of 2,500 RPS with a 1,250 burst, rather than the 10,000/5,000 default used elsewhere. It isn't an error or an account-specific downgrade; it's the standard default for those Regions.

Do HTTP APIs and REST APIs share the same account throttle limit?

Yes. The account-level throttle quota, per Region, applies across HTTP APIs, REST APIs, WebSocket APIs, and WebSocket callback APIs together — they're not throttled as separate pools even though they're different API Gateway product types.

Can one API in my account cause another API to get throttled?

Yes, and this is one of the most confusing versions of this problem to diagnose. Since the account-level bucket is shared across every API in the account and Region, a traffic spike on one API can exhaust the bucket before another, completely unrelated API's requests get their turn — producing 429s on an API whose own traffic and configuration never changed.

How do I tell if a 429 came from throttling and not from a usage plan quota?

Turn on CloudWatch Logs at the ERROR log level and reproduce the failure. A request rejected specifically for exceeding a usage-plan or API-key limit records that reason in the execution log entry; a request throttled at the shared account layer generally will not carry the same per-key message, which is itself the tell.

Does WebSocket API throttling work the same way as REST API throttling?

Mostly, with one difference: WebSocket APIs support route-level throttling that can override the account-level limits for a specific stage or route, configured via the AWS CLI. As with REST APIs, any route-level setting still can't exceed the underlying account-level rate limit.

What should my app do when it gets a 429 from API Gateway?

Resubmit the request, but only after a rate-limiting delay — AWS's own guidance is that the client should catch the exception and retry in a way that itself respects rate limits, rather than retrying immediately. Exponential backoff with jitter is the standard pattern, since it spreads retries out instead of creating another synchronized burst that trips the same throttle again.

Is there a way to see exactly which throttle setting caused a specific 429?

The most reliable way is CloudWatch execution logs at the ERROR level, read alongside the 4XXError metric for the stage. A usage-plan or per-key rejection is generally identifiable directly in the log message; ruling out stage and account-level settings then comes down to comparing the console's configured values against what you'd expect for a healthy request rate.

Can Lambda concurrency limits cause a 429 that looks like API Gateway throttling?

Lambda has its own, separate concurrency and throttling controls, distinct from anything covered in this post. If your API Gateway routes are backed by Lambda, it's worth checking Lambda's own throttling metrics alongside API Gateway's, since the two systems are configured independently and a limit on either side can produce a failed request for the caller.

Does increasing the integration timeout affect my throttle limit?

It can. Raising a REST API's integration timeout beyond the default 29-second cap may require a reduction in your account-level throttle quota for that Region — AWS ties the two together because longer-running integrations, held open at scale, place more load on the same shared capacity.

Will raising my account-level throttle limit cost more money?

The throttle quota increase request itself isn't a billed line item — you're asking for a higher ceiling, not purchasing capacity outright. What costs more is the traffic you then allow through: API Gateway's regular per-request pricing still applies to every request that gets served instead of throttled, so a higher limit that lets through more real traffic will show up in your usual API Gateway usage costs, not as a separate fee for the quota change.

Revision note. Written September 2026, covering current API Gateway account-level, stage-level, and usage-plan throttling behavior for REST, HTTP, and WebSocket APIs. This will need a fresh look if AWS changes the default Regional throttle figures or the Service Quotas request flow described above. If a Saturday rush just cost you a customer over an error you didn't cause, you're not the first — and now you know exactly which bucket to go check.

Related