> For the complete documentation index, see [llms.txt](https://docs.rootcause.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rootcause.ai/more-details/applications/application-modules/while.md).

# While

> Repeat a body subgraph until a condition holds or the iteration cap is reached, carrying state in shift registers.

Repeats its body until `until` comes out true, carrying values from one iteration into the next.

The other frame module, and the only looping one that can feed itself. Each shift register in `shiftRegisters` mints an `sr_<id>` port pair on the node: the in-port seeds it from outside, the out-port carries its value when the loop ends. Inside the body the frame is addressed by the While's own id, so an edge out of the frame reads a register and an edge into it writes what the next iteration will see; a register the body never writes carries unchanged.

`until` is evaluated after each pass and the loop breaks the moment it holds. `maxIterations` breaks it regardless, and `checkpointEvery` decides how often the loop's state is persisted, so a worker that dies mid-loop resumes rather than restarts. Durable only.

## At a glance

|                          |                        |
| ------------------------ | ---------------------- |
| Module type              | `While`                |
| Category                 | Intelligence           |
| Default tier             | `durable`              |
| Runs on                  | `durable`              |
| Starts a flow            | no                     |
| Holds a body             | yes                    |
| Keeps state between runs | no                     |
| Available in             | every application type |

## Parameters

### `shiftRegisters`

`object[]` · required · defaults to `[]`

The values carried from one iteration to the next. Each has an `id`, the port `kind` it carries, and a starting value — either `initialValue` or `initialFromPortId`, never both — and each mints an `sr_<id>` port pair.

### `until`

`string` · required · defaults to `""`

Evaluated after each iteration; the loop breaks the moment it comes out true.

### `maxIterations`

`number` · required · defaults to `12`

The hard bound, whatever `until` says.

### `checkpointEvery`

`number` · required · defaults to `4`

How many iterations between persisted checkpoints, so a dead worker resumes rather than restarts.

### `body`

`FrameBody` · required · defaults to `{"modules":[],"edges":[]}`

The flow run each iteration: its own modules and edges.

## Inputs

| Port | Kind    | Required | Description                                                                                                                           |
| ---- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `on` | `event` | no       | Implicit on every module that does not itself start a flow: wire an event here to make this module the start of what that event runs. |

## Outputs

| Port           | Kind        | Connects to           | Description                                                                      |
| -------------- | ----------- | --------------------- | -------------------------------------------------------------------------------- |
| `iterationLog` | `dataframe` | `dataframe`, `signal` | One row per iteration: when it ran, what `until` evaluated to, and how it ended. |

## Ports it grows

Minted as the module is configured, so a freshly dropped one does not have them yet.

| Port              | Direction | Description                                                                            |
| ----------------- | --------- | -------------------------------------------------------------------------------------- |
| `sr_<registerId>` | in        | A register's initial value; optional, because it may come from `initialValue` instead. |
| `sr_<registerId>` | out       | A shift register's value after the final iteration; one port per register.             |

***

[← All application modules](/more-details/applications/application-modules.md)
