Loops and iteration
A loop repeats a section of the flow once for each item in a list. Everything else in an automation happens once per run; a loop is how you say "do this part again for every one of these."
To add one, click + on an edge and select Loop. This scaffolds a matched pair—a Loop node where the repeated section begins and a Loop End node where it converges—already connected to each other. The nodes you place between them are the loop body, and the body is what runs once per item.
The two nodes are a bracket, and it is the bracket that makes "inside the loop" unambiguous. Everything between them is repeated; everything before or after happens once. A Loop without its Loop End, or the pair wired so they do not properly enclose their body, is a structural problem the editor flags before you can save.
Unlike every other node kind, Loop and Loop End are documented here in full rather than in a catalog page—they only make sense as a pair, and the pair is the concept.
The Loop node
The Loop node opens the bracket. It resolves the list, and then runs the body once per item.
| Field | What it does |
|---|---|
| Source | The list to iterate over, taken from an upstream variable that produces an array—an HTTP response, a search result, a query's matches, a collected set from an earlier step. |
| Mode | Sync runs the iterations one after another; Async runs them at the same time. See below. |
| Failure Policy | What happens when one item's body fails. Fail Fast (the default) stops the loop at the first failure; Best Effort records it and carries on. See below. |
Sync and Async
Sync runs the iterations in order: item two does not begin until item one has finished. Because of that ordering, a Sync iteration can see what earlier iterations produced—which matters when each pass builds on the last, or when the system you are calling will not tolerate concurrent writes to the same thing.
Async starts every iteration at once and lets them run together, bounded only by how much work the engine will run in parallel. It finishes far sooner on a long list, and it is the right choice when the items are genuinely independent of one another. Async iterations cannot see each other's results, and they will not finish in any guaranteed order.
The mode changes nothing else. Both modes produce the same records, run the same body, and report the same way; the only difference is whether one iteration waits for the previous one.
Fail Fast and Best Effort
Fail Fast is the default. When an item's body fails, the loop stops: no further iterations run, and the run ends in failure. This is the right default because a partial result nobody asked for is usually worse than a stopped run—if half the items were processed and the run reported success, you would have no way to tell which half.
Best Effort records the failure and continues with the remaining items. Choose it deliberately, when finishing the other items is genuinely more valuable than stopping—processing ninety-nine items and knowing precisely which one failed beats processing twenty and stopping. It pairs best with work that is safe to repeat, so re-running the automation later completes only what is still outstanding.
Either way, which items failed is recorded per iteration, and the counts arrive on the Loop End node so a later step can branch on whether everything completed cleanly.
Inside the loop body
Within the body, the Loop node's output is the current item. There is no special syntax for it: reference the Loop node through the variable picker and you get this iteration's item, with its fields listed as if it were any other step's output. On iteration one it holds the first item, on iteration two the second.
This is what makes a loop body ordinary. Every node between the brackets is configured exactly as it would be outside one—the only difference is that the value it reads changes each time around.
Body nodes can also read anything upstream of the loop, as usual. Values from before the loop are the same on every iteration; the Loop node's own output is the part that changes.
Loops nest. A loop inside another loop's body runs its own full set of iterations per outer item, and each body node reads whichever loop it is directly inside for its own current item.
Watching a loop run
While a loop runs, the Loop card shows an iteration counter in place of a status badge. Once the run has finished you can step through individual iterations with the arrows beside it—each step replays that iteration's statuses across the body, so you can see which pass a failure happened on rather than only that one did.
The Loop End node
The Loop End node closes the bracket. When every iteration has finished—or the loop has stopped under Fail Fast—the flow continues from here, once, with a summary of what happened.
Its output is always these three values:
| Value | What it holds |
|---|---|
| Iterations | How many items the loop ran over. |
| Succeeded | How many of those completed without failing. |
| Failed | How many failed. |
Because those are declared in advance, a condition placed after the loop can branch on partial failure while you are still building the automation, before anything has run.
The node has one configurable field:
| Field | What it does |
|---|---|
| Collect Results From | A body node's output—its whole payload, or one field of it—to gather from every iteration into a results list on this node's output. |
Collecting results
By default a step after the loop sees only the counts, not what any iteration actually produced. That is often all you need, but not always: if the loop summarized fifty articles, the summaries themselves are the point.
Set Collect Results From to a body node's output, or one field of it, and the Loop End gathers that value from every iteration into a results list, in iteration order. Iterations that did not complete are skipped rather than left as gaps, so under Best Effort the list holds exactly the successes.
The payoff is that a single downstream step can consume everything the loop produced at once—handing all fifty summaries to one AI step, or one message—instead of the flow only knowing how many there were.
How large a list can be
A loop plans all of its iterations at the moment it starts, which means a very long source list would ask the run to expand without limit. A ceiling prevents that: there is a maximum number of steps a single run may expand to across all of its loops, counting every iteration of every body node.
If a loop's list would push the run past that ceiling, the loop fails immediately with a message naming the limit—before doing any of the work, rather than partway through. Only that run is affected; nothing else slows down or stops.
The ceiling is generous for ordinary use, and it is the total for the run rather than for one loop, so a nested loop or a wide body reaches it on a shorter list than a single narrow loop would. If you legitimately need larger fan-out, an administrator can raise it. If you do not, the usual fix is to narrow the source—filter the query, page the results, or split the work across runs.