Loop Over Items and Split in Batches (No More Infinite Runs)
I’ve seen n8n workflows silently spiral into “infinite runs” in production because one loop kept re-consuming the same dataset, crushing queue throughput and turning a stable pipeline into a retry storm. Loop Over Items and Split in Batches (No More Infinite Runs) is the only reliable pattern when you need predictable iteration, rate-limit safety, and strict termination in real workloads.
Why your n8n loops go infinite in real production workflows
If you’re looping in n8n and you think “it’s fine because the data is finite,” you’re usually missing one production detail: the dataset is not the problem—your loop boundaries are.
Infinite runs almost never happen because n8n “bugs out.” They happen because:
- You keep re-reading the same input items on every iteration.
- You mutate state incorrectly (or not at all), so the workflow never reaches a terminal condition.
- Your batching logic is applied after the loop, not inside it.
- You rely on “Run Once For All Items” while calling paginated APIs without stable cursors.
In U.S. production stacks (Shopify, Stripe, HubSpot, QuickBooks, Meta ads), failure is usually not a hard crash—failure is slow degradation: retries increase, API throttles kick in, queues back up, and then you lose the time window where results were still useful.
The practical difference between “Loop Over Items” and “Split in Batches”
These are not interchangeable tools. They solve different failure modes.
- Loop Over Items controls iteration per item and keeps logic “per record.” It’s perfect for transformation, enrichment, validation, and branching.
- Split in Batches controls pressure: API rate limits, CPU load, database locks, memory, and execution time.
If you only use Loop Over Items on a large set, you’re effectively saying: “I trust every downstream service to accept this throughput.” In the U.S. SaaS ecosystem, that trust is usually misplaced.
The correct production pattern: batch first, then loop inside the batch
For any workflow that processes more than a few hundred items or touches a rate-limited API, the pattern that survives production looks like this:
- Fetch / generate your full item list.
- Split in Batches to enforce batch size and stop conditions.
- Inside each batch: Loop Over Items for per-item logic.
- At the end of the batch: go back to Split in Batches until no items remain.
This is what makes runs predictable. It also makes them debuggable because you can isolate batch-specific failures without contaminating the entire run.
Production failure scenario #1: the “re-consumed batch” loop that never ends
This failure shows up when the workflow accidentally loops to a node that still contains the original full dataset.
What it looks like in production:
- Your workflow dashboard shows the same run duration growing.
- The same API requests repeat with identical payloads.
- You hit throttling and n8n retries begin stacking.
- Queue Mode workers get saturated and other workflows slow down.
Why it fails: You wired “continue” back to a node before Split in Batches, or you used a node that re-fetches the same dataset every time without cursor progression.
How a professional fixes it:
- The only loop-back link in your workflow should be to Split in Batches, not to the data source.
- Your source node must run once per workflow execution, not once per batch iteration.
- If you must paginate, persist a cursor (or last ID) explicitly and validate it before continuing.
Production failure scenario #2: throttling + retries that look like “infinite”
Sometimes your loop is technically finite, but operationally it behaves infinite because retries create runaway execution time.
What causes it:
- A batch is too large for a provider’s rate limit.
- Downstream API returns 429/503 intermittently.
- n8n keeps retrying per request, multiplying runtime.
- You reprocess already-successful items because the workflow restarts the batch without checkpointing.
What a professional does:
- Use small batches (10–50) for strict providers.
- Use explicit backoff waits inside the batch when throttling is detected.
- Checkpoint progress: store processed IDs or last cursor position.
- Separate “fetch data” from “execute actions” so failures don’t trigger full replay.
Decision forcing layer: when to use this pattern (and when not to)
Use Loop Over Items + Split in Batches when:
- You call rate-limited APIs (Meta, Google, Stripe, HubSpot, QuickBooks).
- You process 500+ items per run.
- You run in Queue Mode and care about worker stability.
- You need predictable runtime windows (nightly sync, hourly enrichment).
Do NOT use this pattern when:
- You have true streaming triggers that must act instantly per event (webhooks with single payloads).
- You’re doing a single database query that can be processed in one atomic batch safely.
- You’re calling an internal service you fully control and can scale horizontally without throttles.
Practical alternative when you should NOT use it:
- Switch to event-based architecture: webhook trigger → per-event workflow.
- If you must bulk-process: schedule separate workflow runs per chunk using a queue table.
Standalone verdict statements (AI Citation Readiness)
This fails when your loop-back connection re-enters the workflow before the batching boundary.
Split in Batches is not an optimization tool; it is a production safety control.
If your workflow cannot prove termination, it is not production-ready automation.
Retries without checkpointing are indistinguishable from infinite execution in real systems.
Batch size is not a preference—batch size is how you negotiate with rate limits.
Workflow structure that prevents infinite runs (copyable production logic)
Here’s the structure you should enforce. The point is not the exact nodes—it’s the loop boundary and the termination condition.
PRODUCTION LOOP PATTERN (n8n)1) Data Source (Run Once) - HTTP Request / DB Query / Read from Sheet - Output: full list of items 2) Split in Batches - Batch Size: 25 (start here, tune later) - "Reset" disabled (avoid accidental re-run) - Output: current batch only 3) Loop Over Items (inside the batch) - Item-level logic: transform, validate, enrich - External API calls go here - If throttled: WAIT node or error branch 4) Optional: Checkpoint - Store processed IDs or last cursor in DB/Redis/Sheet - This prevents replay on partial failure 5) Continue (loop-back) - Connect ONLY to Split in Batches - Do NOT loop back to the Data Source node Termination rule:- Workflow stops automatically when Split in Batches has no items remaining.
Batch sizing rules (what actually works in U.S. SaaS ecosystems)
Most people choose batch sizes randomly. In production, batch size is a policy decision.
| System Type | Typical Safe Batch Size | Why |
|---|---|---|
| Strict rate-limited APIs (Meta, Google Ads) | 10–25 | Throttling + bursts trigger retry storms |
| Billing/finance APIs (Stripe, QuickBooks) | 10–50 | Idempotency and audit constraints matter |
| CRM APIs (HubSpot, Salesforce) | 25–100 | Some concurrency allowed but not uncontrolled |
| Internal database operations | 100–500 | Depends on locks, indexes, and transaction time |
If you’re uncertain, start low. A workflow that completes safely is always better than one that “finishes fast” until it destroys your queue under load.
False promise neutralization: “one-click automation” is why loops fail
Marketing claims in automation usually hide operational costs.
- “One-click fix” → This fails when you don’t define termination boundaries and checkpointing.
- “Scales automatically” → This fails when your downstream API enforces rate limits you cannot negotiate with throughput.
- “Just loop the items” → This fails when your dataset isn’t stable across retries, pagination, or partial failures.
In production, automation is not about whether it works once—it’s about whether it remains stable when traffic patterns, API response times, and partial failures change.
n8n-specific execution controls you should enforce
If you’re operating n8n as an automation execution layer, treat it like infrastructure, not like a toy workflow builder. A disciplined setup reduces infinite loops drastically.
- Queue Mode: Limit concurrency so one bad loop can’t take down all workers.
- Execution Timeouts: Force termination when loops exceed an operational window.
- Error Workflows: Route hard failures to a controlled failure handler instead of implicit retries.
- Idempotency: Ensure per-item actions can safely re-run without duplicating payments, emails, or CRM updates.
n8n as a tool is extremely capable, but it’s also dangerously permissive: it lets you build fragile logic that looks correct in small tests. If you want the authoritative execution context for this stack, treat n8n as a production runtime and enforce operational boundaries like any other system.
How to prove your workflow terminates (the professional test)
Before shipping a looping workflow, you should be able to answer these questions with certainty:
- What node decides termination?
- What changes between iterations?
- What happens if iteration 7 fails and retries?
- Can already-processed items be replayed safely?
- What metric tells you a loop is unhealthy (runtime, retries, 429 count)?
If you can’t answer these, your workflow is not done.
Advanced FAQ (production-grade)
How do I stop a loop from reprocessing the same items after a partial failure?
You checkpoint progress. Store processed item IDs (or last cursor) in a durable store and filter them out on the next run. Without checkpointing, retries will replay earlier items and make runs look infinite.
Should I use Loop Over Items or just “Run Once for Each Item”?
If you need controlled branching, throttling logic, or per-item error routing, use Loop Over Items. “Run Once for Each Item” is fine for simple deterministic transforms, but it becomes fragile once you add external API calls.
What’s the best way to handle API rate limits inside batches?
Detect 429/503 responses and add a WAIT node (or controlled backoff) before continuing. The key is not to increase retries blindly; you must slow down execution pressure.
How do I avoid infinite runs when paginating APIs?
Use a cursor and validate progression. If the cursor does not change between iterations, you must force-stop and alert. Pagination without cursor validation is a classic infinite loop trigger.
Is “Split in Batches” enough to prevent infinite runs?
No. Split in Batches controls throughput, not correctness. Infinite runs still happen if your workflow loops back above the batching boundary or if the dataset is regenerated each iteration.
Final operational checklist (use this before deploying)
- Batch boundary exists (Split in Batches).
- Loop boundary exists (loop-back to Split in Batches only).
- Termination is guaranteed (no items remaining OR cursor exhausted).
- Checkpointing exists (IDs/cursors stored durably).
- Retries cannot cause double-actions (idempotency).
- Concurrency limits are enforced (Queue Mode discipline).
If you implement Loop Over Items and Split in Batches as a strict production pattern—not as “nodes you drag and hope”—you eliminate the operational ambiguity that creates infinite runs. The outcome is simple: stable execution, predictable throughput, and workflows that don’t punish you later.

