---
title: Loop
description: Execute a set of actions repeatedly based on conditions
---

Repeat a group of steps while your conditions hold, up to a safety limit.

## What it does

Loop has two inputs and two outputs:

* **Input** (top): where the data first comes in.
* **Loop Back** (bottom input): connect the last step of the repeated part here.
* **Loop** (output): the steps to repeat start here.
* **Done** (output): the workflow continues here once the loop ends.

Each time data reaches the node, it checks the **Conditions**. While they hold, it sends the data out of **Loop**; your steps run and come back through **Loop Back**, and the check runs again. As soon as the conditions fail, or the pass count reaches **Max Iterations**, the data leaves through **Done**.

Every pass sends `{ done, currentIndex, inData }`, where `currentIndex` counts the passes from 1 and `inData` is the data that arrived. Use `{{ $input.currentIndex }}` in the repeated steps, for example as a page number.

## When to use it

* Page through an API until it returns no more results.
* Retry a step until it reports success.
* Repeat an action a set number of times.

To work through a long list a few items at a time, [Split in Batches](/nodes/builtin/flow/splitinbatches/) is simpler. Most nodes already run once per item, so you rarely need Loop just to handle every item of a list.

## Inputs and settings

**Max Iterations** accepts 1 to 1,000. The limit stops a loop whose conditions never fail from freezing the tab.

## Outputs

Each output item has these fields:

```json title="Shape of an output item"
{
  "done": true,
  "currentIndex": 0,
  "inData": null
}
```

When the loop exits through **Done**, its pass counter resets, so a loop nested inside another loop starts again from 1 on the next outer pass.

## Dependencies and credentials

None. This node needs no connection and has no slots for other nodes.

## Example workflow

Fetch every page of a paginated API:

1. A [Set Variable](/nodes/builtin/flow/setvariable/) node sets `hasMore` to `true`.
2. Loop with the condition `{{ $run.hasMore }}` (**Boolean**) is true, **Max Iterations** 50.
3. From **Loop**: [Http Request](/nodes/builtin/core/http-request/) to `https://api.example.com/items?page={{ $input.currentIndex }}`, then Set Variable stores the response's `hasMore` flag. Connect it back to **Loop Back**.
4. From **Done**: continue with the collected data.

## Common issues

* **The loop stops after one pass.** The conditions were false on the second check. Make sure the repeated steps update the value the condition reads, and that the last step is connected to **Loop Back**, not to the top input.
* **The loop always runs exactly Max Iterations times.** The conditions never become false. Check the field and operator, or raise the limit if the work really needs more passes.
* **Nothing runs after the loop.** Connect the next steps to **Done**, not to **Loop**.

## Related nodes

* [Split in Batches](/nodes/builtin/flow/splitinbatches/): work through a list a batch at a time.
* [IF](/nodes/builtin/flow/if/): the same kind of conditions, without repeating.
* [Poll Until](/nodes/builtin/flow/polluntil/): call a URL repeatedly until the response says it is done.
* [Wait](/nodes/builtin/flow/wait/): pause between passes.