---
id: flow--range-plugin
title: "Range"
summary: "Loop component: calls `Output` once for every integer from `Start` (inclusive) to `End` (exclusive) with the same input record, then calls `Continue` once. The current index is available in the metadata property `RangeInfo`."
audience: user
keywords: "input, output, continue, start, end, batchmode"
---
# Range

Loop component: calls `Output` once for every integer from `Start` (inclusive) to `End` (exclusive) with the same input record, then calls `Continue` once. The current index is available in the metadata property `RangeInfo`.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | any | Record that is sent on every iteration. |
| Output | output | same as input | Called once per index, sequentially. |
| Continue | continue | same as input | Called once after the loop has finished. |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `Start` | integer | `0` | Required. First index (included). |
| `End` | integer | `10` | Required. End of the range (excluded). |
| `BatchMode` | dropdown: `1` Auto, `2` Always, `3` Never | `1` | Whether the iterations of one run form a batch for batch consumers (Bulk insert, Write file, Build array, ...). `Auto`: only if the input record is not already in a batch (Timer); inside a batch the iterations stay in it. `Always`: a child batch per run. `Never`: no batch. |

## Behaviour

- For `i = Start; i < End; i++`: sets metadata `RangeInfo.Value` (`Viaducta.Plugins.RangePlugin.RangePluginMetaData`, property `Value` integer) to `i` and calls `Output` with the original record and a copy of the metadata (each emission has its own, so a component that keeps it, such as a queue or Build array, still sees its own index), waiting until the downstream branch completes before the next iteration. `Start = 0`, `End = 10` gives 10 iterations, indexes 0..9.
- If `End <= Start` there are no iterations.
- If `Output` has no connections the loop is skipped entirely.
- When a batch is opened (`BatchMode`) it ends after the last iteration was processed downstream and before `Continue`: consumers commit then (e.g. Timer → Range → Data sample → Bulk insert inserts all rows of the run together). An error in the `Output` branch or a flow stop fails it and the consumers roll back.
- After the loop, `Continue` is called once with the original record; `RangeInfo.Value` then holds the last index (or `0` if there were no iterations).
- The component progress is updated after each iteration.
- When the flow is stopped (cancellation) the loop ends and `Continue` is not called.
- An exception in the `Output` branch ends the loop and is passed back to the caller; `Continue` is not called.

## Notes

- All iterations share the same metadata instance (the batch copy when a batch is opened) and the same input record. Changes made downstream are visible in the next iteration.
- Nested Range components write to the same `RangeInfo` property, so an inner Range overwrites the outer index. Copy the outer value elsewhere (e.g. into the record) before entering the inner loop.
- Iterations are sequential, not parallel. Work handed off to other threads downstream (queues, async components) is not awaited.
- `Start` / `End` can be set with expressions to loop over a dynamic count.

## Example

```json
{ "Start": 1, "End": 6 }
```

Timer → **Range** → Http client (page `RangeInfo.Value`) → ... ; `Continue` → Log
