---
id: flow--for-each
title: "For each"
summary: "Splits a list property of the input record into single items and sends each item to `Output`, sequentially or in parallel. Use it to process the elements of a list one by one (call an API per item, map items, write them to a database)."
audience: user
keywords: "input, output, inputproperty, nowrap, parallelrun, maxparallelslots, batchmode"
---
# For each

Splits a list property of the input record into single items and sends each item to `Output`, sequentially or in parallel. Use it to process the elements of a list one by one (call an API per item, map items, write them to a database).

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | any (a flow type with a list or array property) | The record containing the list. |
| Output | output | generated `<flow namespace>.ForEach<InputTypeName><InputProperty>` or `Viaducta.TypeSystem.Metadata.AnyData` | One record per list item (see `NoWrap`). |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `InputProperty` | dropdown (property name) | | Required. The list or array property of the input type to iterate. The options are the list/array properties of the input connection's type (flow types only). Selecting it regenerates the output type. |
| `NoWrap` | boolean | `true` | `true`: items are sent as they are. `false`: each item is wrapped in a generated record with one property `Value`. |
| `ParallelRun` | boolean | `false` | Process the items in parallel. |
| `MaxParallelSlots` | integer (1-512) | `4` | Maximum parallel items when `ParallelRun` is `true`; capped at the number of processor cores. |
| `BatchMode` | dropdown: `1` Auto, `2` Always, `3` Never | `1` | Whether the items of one list form a batch for batch consumers (Build array, Bulk insert, Write file, ...). `Auto`: only if the input record is not already in a batch; inside a batch (e.g. a file read by Read file) the items stay in that batch. `Always`: a child batch per list, e.g. to rebuild every list with Build array. `Never`: no batch. |

## Behaviour

- Reconfigure on `InputProperty`:
  - `NoWrap` = `false`: creates the flow type `ForEach<InputTypeName><InputProperty>` with a property `Value` of the item type and makes it the output type. Each item is emitted as a new record of this type with `Value` set to the item.
  - `NoWrap` = `true`: the output pin type is `AnyData`. Set the type of the outgoing connection to the item type (a flow type) and the items are emitted as that type; otherwise each item is wrapped in `AnyData`.
- For each input record the items of `InputProperty` are emitted in list order (sequential) or concurrently (parallel). The loop is synchronous: the For each finishes only after all items have been processed downstream (combine with Sync call to run something after the loop).
- Every item carries the metadata of the input record (the batch copy when a batch is opened); in parallel mode every item gets its own copy. For each does not provide the item index.
- When a batch is opened (`BatchMode`) it ends after the last item was processed downstream: consumers commit then; an error that reaches For each fails it and the consumers roll back.
- A `null` or empty list emits nothing. Without an outgoing connection nothing is processed.

## Notes

- Changing `NoWrap` alone does not regenerate the output type; re-select `InputProperty` (or use its reconfigure button) after changing `NoWrap`.
- A Build array after a For each collects per batch: with `BatchMode` `Auto` and no incoming batch that is one array per list; inside an incoming batch use `Always` to get one array per list.
- In parallel mode expect the output order to differ from the list order.
- Inside an open *Sql transaction* the items are always processed sequentially (`ParallelRun` is ignored), because the transaction's connection can't be shared by parallel items.
- Only list/array properties of flow types are offered; lists of plugin types must be typed in by name.

## Example

```json
{ "InputProperty": "Orders", "NoWrap": true, "ParallelRun": false, "MaxParallelSlots": 4 }
```

Json deserializer → **For each** (connection type `MyFlow.Order`) → Http client → ...
