Loops in n8n: Mastering Loop Over Items (Split in Batches)
Published 26 July 2026 · 7 min read
"How do I write a loop in n8n?" is probably the most common question from people arriving from a classic programming language — and the answer is surprising: most of the time, there is nothing to do. n8n iterates natively over items, and the reflex of wrapping everything in an explicit loop produces workflows that are slower and more fragile. There remains a family of cases where a real loop is genuinely required, and there, one node matters: Loop Over Items (formerly Split in Batches). This guide covers when to use it, how to wire it without falling into the classic traps, and which alternatives to consider when it hits its limits.
The #1 beginner trap: n8n already loops on its own
In n8n, data flows as a list of items, and almost every node automatically runs once per item it receives. A node that returns 50 contacts, followed by a Set node that reshapes the fields, then an HTTP Request node that calls an API: all three steps process the 50 contacts without any loop being declared. That is n8n's default execution model — the implicit equivalent of a for each on every node.
The direct consequence: wrapping every step in a Loop Over Items with a Batch Size of 1 "just to be safe" is not only pointless but counterproductive — each iteration adds execution overhead, and the workflow becomes unreadable. Before adding a loop, ask yourself: doesn't the next node already do the work item by item? Nine times out of ten, the answer is yes.
When a real loop is required
Some situations remain where native iteration isn't enough, because the need isn't about each item but about the pace or grouping of the processing:
- Processing in batches: sending 500 rows to an AI model in packs of 20 to build grouped prompts, or inserting into a database in blocks rather than 500 single-row queries.
- Inserting a pause between batches: an API with a tight quota (typically an AI API) rejects bursts; you need to space out the calls, which native iteration cannot do.
- Calling a paginated API with logic the HTTP Request node's native option cannot express — the pattern detailed in our guide to API pagination in n8n.
- Processing sequentially when order matters: each step depends on the previous one's result (numbering, running balance, ordered writes into a document).
If your need doesn't fit any of these cases, native iteration will do the job — possibly combined with a Merge node to recombine branches.
The Loop Over Items node: Batch Size, loop, and done
The node is called Loop Over Items in recent versions of n8n (you will still run into its old name, Split in Batches, in many tutorials and shared workflows — it's the same node). How it works comes down to three elements:
- Batch Size: the number of items emitted on each iteration.
1for strictly sequential item-by-item processing,10or20for batches. - The "loop" output: emits the current batch. This is where the processing to repeat connects — and the last node of that processing must be wired back into the Loop Over Items input to trigger the next iteration.
- The "done" output: only fires once every batch has been consumed, and then emits all the items that went through the loop. This is where the rest of the workflow connects.
The typical wiring looks like this:
Source (500 items)
→ Loop Over Items (Batch Size: 20)
├─ loop → OpenAI → Set → (back to Loop Over Items)
└─ done → Google Sheets (writes all 500 results)
The classic mistake — responsible for a good share of the "my loop doesn't work" posts on the forums — is connecting the rest of the workflow to the wrong output: on loop, the continuation runs on every iteration with a partial batch; and if nothing returns to the node's input, the loop stops after the first batch without ever firing done. Remember the rule: the repeated processing leaves from loop and comes back to it; everything that runs after the loop leaves from done.
Adding a Wait node inside the loop to respect a rate limit
The most common use case in 2026: calling an AI model over hundreds of items without triggering 429 errors. The solution comes down to a Wait node placed inside the loop, right before the connection back to Loop Over Items:
Loop Over Items (Batch Size: 10)
├─ loop → OpenAI (10 calls) → Wait (Amount: 5, Unit: Seconds) → back to loop
└─ done → rest of the workflow
Each batch of 10 calls is followed by a pause of a few seconds, spreading the load and keeping the throughput under the API's quota. The right value depends on your provider's actual limit — check its documentation rather than guessing, and combine the pause with the backoff strategies described in our guide to AI API rate limits. For any residual errors, a properly configured retry on the HTTP Request node completes the setup.
Collecting the results after the loop
A reassuring point for anyone looking for where to "accumulate" their results: there is nothing to do. The done output emits all the items that traveled through the loop, with the fields added or modified on each iteration. A Google Sheets, Postgres, or Slack node connected to done therefore receives the complete list of all 500 enriched items, in one go. If you need an aggregation (count, sum, group), a Code or Aggregate node placed after done works over the full set.
Throughput, batches, and total time: the intuition behind Little's law
Slowing a loop down to stay under a rate limit has a mechanical cost: the total runtime stretches out. That's not an n8n flaw — it's a throughput/latency trade-off formalized long ago by queuing theory. The foundational result is Little's law, proved by John D. C. Little in "A Proof for the Queuing Formula: L = λW" (Operations Research, 1961 — see on Google Scholar): the number of jobs in progress in a system equals its throughput multiplied by the average time spent in the system. Translated for your workflows: at a given volume, if you halve the throughput (a longer pause, smaller batches), the traversal time doubles. So don't hunt for a magic setting — pick the maximum throughput the API tolerates, and accept the total time that follows from it, or parallelize (see below).
Alternatives to Loop Over Items
Three options cover the cases where the node reaches its limits:
- A sub-workflow called per batch: the loop calls a child workflow via Execute Sub-workflow, which processes one batch and hands control back. Each batch runs in an isolated context — memory freed between batches, logic that's reusable and testable on its own. That's the pattern detailed in our guide to n8n sub-workflows.
- The Code node to loop in JavaScript: a
foror areduceinside a Code node processes thousands of items in a single node execution, without the overhead of visual iterations — ideal for pure transformations with no external calls. See our guide to expressions and the Code node. - Queue mode to parallelize at scale: when the volume exceeds what a sequential run can absorb, distributing the work across several workers via n8n's queue mode with Redis beats a giant loop hands down.
Pitfalls to avoid
- The infinite loop: if an IF inside the loop diverts some items without ever bringing them back to Loop Over Items, or if the continuation is connected to
loopinstead ofdone, the run spins forever or stops halfway. Always test with a small dataset (5 to 10 items) before launching the real volume. - Memory on very large volumes: every item in the loop stays in memory until the
doneoutput fires. With tens of thousands of items enriched with large payloads, the run can slow down dramatically or fail outright. Write as you go (a database insert on each batch, inside theloopbranch) rather than waiting fordone, or switch to the sub-workflow pattern. - Defaulting to a Batch Size of 1: strictly sequential means maximum total time. Only choose it when order or isolation genuinely requires it; otherwise, a batch of 10 or 20 divides the number of iterations accordingly.
Going further
Loop Over Items is a simple node once you've internalized its two rules: n8n already iterates natively (the explicit loop is the exception, not the norm), and the repeated processing leaves from loop and returns to it, while the rest of the workflow lives on done. FlowKit's ready-to-use n8n workflows apply these patterns everywhere batch processing or a rate limit demands it — bounded loops, calibrated Wait nodes, write-as-you-go — so you don't have to rediscover these traps one Monday morning in production.
FAQ
Frequently asked questions
Do I need a Loop Over Items node to process a list of items in n8n?
In most cases, no: n8n iterates natively. Almost every node runs automatically once per item it receives. A Set, HTTP Request, or OpenAI node placed after a node that returns 50 items will process all 50, with no explicit loop. Loop Over Items only becomes useful when you need to process in batches, insert a pause between batches, or force sequential processing.
What is the difference between the loop and done outputs of Loop Over Items?
The loop output emits the current batch on each iteration: that is where you connect the processing to repeat, and its last node must be wired back into the Loop Over Items input to trigger the next batch. The done output only fires once every batch has been processed and emits all the accumulated items: that is where the rest of the workflow connects.
How do I slow down an n8n loop to respect an API rate limit?
Place a Wait node inside the loop, between the batch processing and the connection back to Loop Over Items. Each iteration then pauses for a fixed duration (a few seconds, for example), spreading the calls over time. Adjusting Batch Size and the Wait duration lets you stay under the API limit while keeping the total runtime acceptable.
Why does my Loop Over Items loop never stop?
The classic case: the end of the batch processing is not wired back into the Loop Over Items input, or the rest of the workflow is connected to the loop output instead of done. The node can then never exhaust its batches or fire done. Checking that the loop returns to Loop Over Items and that the done output carries the rest of the workflow fixes nearly every case.
Bundle FlowKit Complet
€269