n8n Rate Limit 429 Errors: Batching, Backoff, Fixes

automation
A worn red take-a-number ticket dispenser on a blush pink wall with a curl of paper tickets hanging from it, a metaphor for pacing n8n API requests to stay under a rate limit
Rate limits are a queue with rules. Your workflow either waits its turn on purpose or gets told to by a 429.

An n8n rate limit 429 error means the API you're calling told your workflow to slow down. "The service is receiving too many requests from you" is n8n's label for HTTP 429: you sent more requests in a time window than the API allows, and the fix is pacing, not retrying harder. For a per-second limit, Retry On Fail or HTTP Request batching is enough. For per-minute quotas, use a Wait node loop. And if several workflows share one API key, you need a shared counter, because nothing inside a single execution can see the others.

We've built 200+ n8n workflows for clients, and 429s show up in a predictable spot: the workflow works perfectly in testing with five items, then dies on the first real run with 3,000. That isn't bad luck. It's math you can do before you hit run.

What causes a 429 error in n8n?

Every serious API meters you. The meter has three parts, and you need all three before you pick a fix:

  • The window. Per second (Stripe, most CRMs), per 10 seconds (HubSpot's burst limit), per minute (Google Sheets) or per day (many enrichment APIs).
  • The scope. Per access token, per user, per app or per project. Google Sheets, for example, allows 300 read requests per minute per project but only 60 per minute per user per project, per Google's published Sheets API limits.
  • What counts as a request. One n8n node run with 500 items usually means 500 API calls. n8n runs most nodes once per item, so the item count is your request count.

That last point is where most of our 429 tickets come from. Someone builds a "look up the row, then update the row" pattern with the Google Sheets node, feeds it a 400-item list, and asks for 800 calls in a few seconds against a 60-per-minute budget. The first 60 go through. Everything after that fails.

Do the math first: items × calls per item ÷ the limit = the minimum time this run needs. If that number is 13 minutes, no retry setting will make it 30 seconds.

Is Retry On Fail enough to fix rate limits?

Sometimes. It's the first thing people reach for and it's fine for short spikes, but it has hard ceilings that most tutorials skip.

In a node's Settings tab, Retry On Fail gives you Max Tries (up to 5) and Wait Between Tries (up to 5,000 ms). So the longest a node can wait across all its retries is about 20 seconds, at a fixed interval, with no jitter.

Here's what that means in practice:

  • Per-second limits: Retry On Fail usually works. Wait 1,000 to 2,000 ms and the window has reset by the next try.
  • Per-minute limits: it usually doesn't. Five tries five seconds apart all land inside the same minute that's already exhausted.
  • Daily limits: it never works. You're done until the quota resets.

There's a second catch. When a node processes many items and fails on item 61, the retry reruns the node, and every retry fires the burst again. You can hammer an API harder with retries on than with them off. We've also seen retry behavior get ignored when On Error is set to one of the continue options, so test the combination before trusting it.

Use Retry On Fail as a safety net for occasional blips, not as your rate limiting strategy.

How do you add a delay between requests in n8n?

You have two built-in tools. Pick based on which node makes the call.

HTTP Request node batching

If the call goes through the HTTP Request node, open Add Option → Batching and set:

  • Items per Batch: how many items go out together
  • Batch Interval (ms): how long to pause between batches

For a 60-per-minute API, 1 item per batch with a 1,100 ms interval keeps you just under the limit with a little headroom. We always leave 10 to 20% headroom because other things (a person testing in the UI, another workflow) eat into the same budget.

This is the cleanest fix when it applies. It's covered in n8n's own rate limit handling docs, and it keeps the workflow canvas readable.

Loop Over Items plus a Wait node

App nodes like Google Sheets, HubSpot or Airtable don't have a batching option. For those, build the loop by hand:

  1. Loop Over Items with a batch size that fits the window (say 50 for a 60-per-minute API).
  2. The API node(s) inside the loop.
  3. A Wait node set to resume after a time interval (61 seconds here), connected back to Loop Over Items.

Count the calls inside the loop, not the nodes. A "find row, then update row" pair inside the loop is two calls per item, so a batch of 50 is 100 calls. That's the mistake that makes people think the Wait node "doesn't work."

Batching paces one execution. It doesn't know any other execution exists. Keep that in mind; it matters in a minute.

How do you handle 429 with exponential backoff in n8n?

Pacing prevents most 429s. Backoff handles the rest: the ones you couldn't predict because the limit is dynamic, shared or undocumented.

The pattern we use on the HTTP Request node:

  1. Turn on Options → Response → Include Response Headers and Status and Never Error. Now a 429 comes out as data (statusCode, headers) instead of killing the execution.
  2. Add an IF node: statusCode equals 429.
  3. On the true branch, a small Code node works out the wait:
const headers = $json.headers || {};
const retryAfter = Number(headers['retry-after']);
const attempt = $runIndex; // how many times this branch has already run

if (attempt >= 6) {
  throw new Error('Still rate limited after 6 attempts, giving up');
}

const backoff = Math.min(2 ** attempt, 64) + Math.random();
return [{ json: { ...$json, waitSeconds: retryAfter > 0 ? retryAfter : backoff } }];
  1. A Wait node that resumes after {{ $json.waitSeconds }} seconds, connected back to the HTTP Request node.

Two details make this hold up in production. First, respect Retry-After when the API sends it. The API knows when your window resets; your guess doesn't. Second, add jitter and a cap. Google recommends truncated exponential backoff with a random component and a maximum of 32 to 64 seconds, because a dozen clients retrying at the exact same moment just recreate the spike.

The hard stop at six attempts matters too. A workflow that retries forever turns a rate limit into a stuck execution nobody notices. Pair it with an error workflow so the failure reaches a human; we cover that setup in our guide to n8n error handling and monitoring.

Why do 429s keep happening after you add batching?

This is the part almost nobody writes about, and it's the most common reason a "fixed" workflow starts failing again a month later.

Batching and Wait loops are local. Rate limits are global. The API counts every request on your token, no matter which workflow or execution sent it. These all share one budget without knowing about each other:

  • Parallel executions of the same workflow. A webhook-triggered workflow that receives 40 leads in a minute runs 40 executions, each pacing itself perfectly and together blowing through the limit.
  • Different workflows on the same credential. The nightly sync, the lead router and the reporting workflow all use the same HubSpot private app token.
  • Queue mode workers. Each worker runs several executions at once (the default concurrency is 10 per worker). Add workers to go faster and you also multiply your burst. We break down that trade-off in how many n8n queue mode workers you actually need.
  • Agency setups. Several client workflows pointed at one shared enrichment or SMS API key.

The fix is a shared counter every workflow checks before it calls the API. We use Redis because most of our self-hosted queue mode instances already run it:

  1. Build a key from the API name and the current window, like rl:hubspot: plus the current 10-second slot.
  2. Use the Redis node's Increment operation on that key, with expire turned on and a TTL equal to the window.
  3. If the returned count is over your limit (minus headroom), Wait until the next window and try again. Otherwise, make the call.

Wrap those steps in one sub-workflow, call it from everywhere that hits that API, and you have one throttle for the whole instance. It's a fixed-window counter, not a perfect token bucket, but in our experience it removes the large majority of shared-quota 429s, and it's simple enough that the next person to open the workflow understands it.

If you don't run Redis, a Postgres row with an atomic UPDATE ... RETURNING does the same job. Don't use workflow static data for this; it isn't shared across executions the way you'd need.

What about Google Sheets "quota exceeded" errors?

Google Sheets deserves its own section because it's the most common 429 we fix, usually in workflows that started as a quick prototype and became a production system.

The error reads something like Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute per user'. The 60-per-minute per-user limit is the one you'll hit, and it applies to reads and writes separately.

What actually fixes it, in order of impact:

  • Read once, not per item. Pull the whole sheet (or range) in one call at the start, then match rows in n8n with a Merge or Code node. A 400-row lookup drops from 400 reads to 1.
  • Write in bulk. Collect updates and send them as one append or update operation instead of one call per row.
  • Slow the trigger. A Google Sheets Trigger polling every minute across several workflows eats your read budget before any real work starts.
  • Move the data. If a sheet is acting as a database for thousands of rows and several workflows, it's the wrong tool. We usually move it to Postgres or n8n Data Tables; here's how we decide between n8n Data Tables and an external database.

Requesting a quota increase from Google is possible, but it's the last resort. Cutting calls is faster and permanent.

Which fix should you use?

Short version, based on what we see across client instances:

  • Occasional 429 on a per-second API: Retry On Fail, 3 tries, 1,000 to 2,000 ms.
  • Big list into an HTTP API: HTTP Request batching sized to the limit with 10 to 20% headroom.
  • Big list into an app node (Sheets, Airtable, HubSpot): Loop Over Items plus Wait, counting calls inside the loop.
  • Unpredictable or undocumented limits: Never Error plus an IF on 429 plus Retry-After-aware backoff with a cap.
  • Many workflows, executions or workers on one key: a shared Redis or Postgres counter in a sub-workflow.
  • Any of the above: first, cut the number of calls. It's always the cheapest fix.

Most real workflows need two of these: call reduction plus one pacing method, with backoff as the safety net. Rate limits also come up in every migration we run, because Zapier and Make throttle tasks for you in ways n8n doesn't. If you're moving over, our Zapier and Make to n8n migration guide covers what else changes.

Get a free automation audit

If your n8n instance is throwing 429s, failing silently overnight or getting slower as you add clients, we'll look at it with you. Our team reviews the workflows, maps which ones share API budgets and shows you exactly where the calls are going. Get a Free Automation Audit, or see how we build and run production workflows on our n8n workflow automation service page.