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 Requestsin the HTTP Request node- Workflow fails partway through large datasets
- Works fine with small test batches, breaks in production
- Some APIs return
503 Service Unavailableinstead of 429 when overloaded
Common culprits and their limits:
| API | Rate limit |
|---|---|
| OpenAI GPT-4o | 500 RPM (tier 1), 5,000 RPM (tier 4) |
| Airtable | 5 requests/sec per base |
| Slack | 1 message/sec per channel |
| HubSpot | 100 requests/10 sec |
| Notion | 3 requests/sec |
| Google Sheets | 60 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:
- Click + after your HTTP Request node
- Search for Wait
- Set Resume to
After time interval - 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:
- Add a Loop Over Items node before your HTTP Request
- 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:
- Open the node settings (gear icon or Options section)
- Enable Retry On Fail
- Set Max Tries to
3 - 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:
- Set batch size to your production volume
- Enable Test with all items in the trigger
- 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