n8n Rate Limiting: Avoid API Throttle in Automation

Stop API throttle errors in n8n. Configure rate limiting with Wait nodes, batch splitting, and retry logic to keep workflows running reliably.

Problem: Your n8n Workflow Hits 429 Errors Mid-Run

You build an n8n workflow that calls an external API — OpenAI, Airtable, Slack, HubSpot — and it works fine for 10 items. Then you feed it 500 records and it starts failing with 429 Too Many Requests or silently drops items.

You'll learn:

  • How to add per-request delays using the Wait node
  • How to split large batches to stay under rate limits
  • How to set up automatic retry logic with exponential backoff
  • How to handle per-minute vs per-day API limits differently

Time: 20 min | Difficulty: Intermediate


Why This Happens

n8n processes items as fast as the host machine allows. When you pass 200 items into an HTTP Request node, n8n fires all 200 requests in parallel or near-parallel — with no awareness of what the target API allows.

Symptoms:

  • Error: 429 Too Many Requests in the HTTP Request node
  • Workflow fails partway through large datasets
  • Works fine with small test batches, breaks in production
  • Some APIs return 503 Service Unavailable instead of 429 when overloaded

Common culprits and their limits:

APIRate limit
OpenAI GPT-4o500 RPM (tier 1), 5,000 RPM (tier 4)
Airtable5 requests/sec per base
Slack1 message/sec per channel
HubSpot100 requests/10 sec
Notion3 requests/sec
Google Sheets60 requests/min per user

Solution

Step 1: Add a Wait Node Between API Calls

The simplest fix. Drop a Wait node after your HTTP Request node to pace requests.

In your workflow canvas:

  1. Click + after your HTTP Request node
  2. Search for Wait
  3. Set Resume to After time interval
  4. Set the interval based on your API's limit
Airtable (5 req/sec) → Wait 250ms between each item
OpenAI tier 1 (500 RPM) → Wait 120ms to stay under ~480 RPM
Slack (1 msg/sec per channel) → Wait 1100ms for safety margin

Use slightly longer than the minimum — a 10% buffer avoids edge cases at the API gateway level.

Expected result: Your workflow slows down but completes without 429 errors.

If it still fails: The API may enforce per-minute and per-hour limits. Check the response headers — most APIs return Retry-After or X-RateLimit-Reset.


Step 2: Split Large Inputs into Batches

The Wait node throttles per-item. For bulk operations, you also need to control how many items are in flight at once.

Use the Loop Over Items node to process in chunks:

  1. Add a Loop Over Items node before your HTTP Request
  2. Set Batch Size to a safe number for your API
Airtable: Batch Size = 5, Wait = 200ms
OpenAI: Batch Size = 10, Wait = 500ms
HubSpot: Batch Size = 8, Wait = 100ms

Your workflow structure should look like this:

Trigger → [Data source] → Loop Over Items → HTTP Request → Wait → [Merge/Output]
                               ↑                                        |
                               └────────────── loop back ───────────────┘

The Loop Over Items node handles the iteration — you don't need a separate split node.

If you're already using SplitInBatches (older workflows): It still works, but Loop Over Items is the current replacement in n8n 1.x. Migrate when you next touch the workflow.


Step 3: Add Retry Logic for Transient 429s

Even with rate limiting, you'll occasionally hit 429s from API spikes, cold starts, or brief quota resets. Retries with backoff catch these without failing the whole workflow.

In the HTTP Request node settings:

  1. Open the node settings (gear icon or Options section)
  2. Enable Retry On Fail
  3. Set Max Tries to 3
  4. Set Wait Between Tries to 2000 (2 seconds)

For APIs with Retry-After headers, you can read the value and feed it into a dynamic Wait:

// In a Code node after a failed HTTP Request
// Access the error response headers
const retryAfter = $input.first().json.headers['retry-after'];
const waitMs = retryAfter ? parseInt(retryAfter) * 1000 : 2000;

return [{ json: { waitMs } }];

Then connect a Wait node set to Resume After with the waitMs value from the expression field: {{ $json.waitMs }}.


Step 4: Handle Per-Minute vs Per-Day Limits Separately

Some APIs have two layers of limits: a burst rate (requests per second/minute) and a daily quota.

Per-minute limits → fix with Wait node + batch size (Steps 1–2).

Daily quotas → require a different approach. Use n8n's Schedule Trigger to spread work across hours:

Instead of: run 10,000 items at 9am
Do this:    run 1,000 items every hour via Schedule Trigger

For OpenAI's daily token limit, log token usage in Airtable or a Postgres database and check it at the start of each scheduled run:

// Code node: check remaining daily budget
const used = $input.first().json.tokensUsedToday;
const limit = 1000000; // your daily token limit
const remaining = limit - used;

if (remaining < 10000) {
  // Return empty array to stop the workflow gracefully
  return [];
}

return $input.all();

If the workflow should alert you instead of silently stopping: Route the empty-array case to a Slack or email node first.


Verification

Run your workflow with a controlled batch of 50 items and monitor execution:

n8n execution log → check for 429 errors
Target API dashboard → verify request count didn't exceed limit
Execution time → confirm Wait nodes are adding delay

You should see: All 50 items complete successfully, execution time is proportionally longer, and zero 429 errors in the log.

To stress-test before going to production:

  1. Set batch size to your production volume
  2. Enable Test with all items in the trigger
  3. Watch the execution timeline — each HTTP Request node should show staggered timestamps

What You Learned

  • n8n doesn't throttle by default — you own rate limiting in your workflow
  • Wait node + Loop Over Items batch size is the standard pattern for most APIs
  • Retry On Fail handles transient errors; it doesn't replace deliberate throttling
  • Per-day limits need architecture changes (scheduled batches), not just delays

Common mistake: Adding a Wait node after a Loop that processes all items at once. The Wait only helps if it's inside the loop, between iterations.

When NOT to use this approach: If you control the target API (e.g., your own FastAPI backend), it's faster to raise the rate limit server-side than to slow n8n down.

Tested on n8n 1.82, self-hosted via Docker on Ubuntu 24.04