Loop
The Loop node repeats a set of steps based on a specified iteration strategy. It supports five loop types: numeric counting, while-condition, JSONPath iteration, XMLPath iteration, and variable-based iteration. Loops are essential for processing collections of data, retrying operations, and batch workflows.
Before You Use This Node
| What you may need | Where to set it up | Why it matters |
|---|---|---|
| Lists or reusable business records | Datasets | Use prepared data when the loop needs to process a known list. |
| Limits, counters, or stop conditions | Global Variables | Keep loop rules easy to change without editing every workflow. |
Actions
| Action | Description |
|---|---|
loop:number | Iterate a fixed number of times |
loop:while | Iterate while a condition is true |
loop:jsonPath | Iterate over elements matched by a JSONPath expression |
loop:xmlPath | Iterate over elements matched by an XPath expression |
loop:variable | Iterate over elements in a variable (array) |
loop:number
Executes the loop body a fixed number of times. A zero-based index variable is available in each iteration.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
count | integer | Yes | Number of iterations |
indexVariable | string | No | Variable name for the current index. Defaults to loopIndex |
steps | array | Yes | Steps to execute in each iteration |
loop:while
Executes the loop body as long as the specified condition evaluates to true. A maximum iteration limit prevents infinite loops.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
condition | object | Yes | Condition to evaluate before each iteration |
condition.left | any | Yes | Left-hand operand |
condition.operator | string | Yes | Comparison operator (same as Conditional node) |
condition.right | any | Yes | Right-hand operand |
maxIterations | integer | No | Safety limit. Defaults to 100 |
steps | array | Yes | Steps to execute in each iteration |
loop:jsonPath
Iterates over elements that match a JSONPath expression applied to the input data.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input | any | Yes | The JSON data to apply the JSONPath expression to |
jsonPath | string | Yes | JSONPath expression (e.g., $.orders[*], $.data.items[?(@.status=='active')]) |
itemVariable | string | No | Variable name for the current item. Defaults to loopItem |
steps | array | Yes | Steps to execute for each matched element |
loop:xmlPath
Iterates over elements that match an XPath expression in XML data.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input | string | Yes | XML content |
xpath | string | Yes | XPath expression (e.g., //order, /root/items/item[@status='active']) |
itemVariable | string | No | Variable name for the current element. Defaults to loopItem |
steps | array | Yes | Steps to execute for each matched element |
loop:variable
Iterates over elements in a variable that holds an array.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
variable | string | Yes | Variable name or reference containing an array |
itemVariable | string | No | Variable name for the current item. Defaults to loopItem |
indexVariable | string | No | Variable name for the current index. Defaults to loopIndex |
steps | array | Yes | Steps to execute for each element |
JSONPath Syntax Guide
JSONPath is used by loop:jsonPath to select elements from JSON data. The expression always starts with $ representing the root of the JSON document.
Common Patterns
| JSONPath Expression | Description |
|---|---|
$.items | The items array at the root level |
$.items[*] | Each element in the items array |
$.data.customers[*] | Each customer object inside data.customers |
$.orders[?(@.status=='active')] | Only orders where the status field equals active |
$.orders[?(@.total > 100)] | Only orders where total is greater than 100 |
$.results[0:5] | The first 5 elements of the results array (array slice, indices 0 through 4) |
$.results[-1] | The last element of the results array |
$..name | All name fields at any depth in the document (recursive descent) |
$..items[*].name | The name field of every item in every items array, at any depth |
$.store.book[?(@.price < 10)].title | Titles of books priced under 10 |
Filter Expressions
Filter expressions use the ?() syntax inside array brackets. The @ symbol refers to the current element being evaluated.
@.field == 'value'-- equality check@.field != 'value'-- inequality check@.field > 100-- numeric comparison@.field-- truthy check (field exists and is not null/empty)
Example input and expression:
Given this JSON data:
{
"orders": [
{ "id": 1, "status": "active", "total": 250 },
{ "id": 2, "status": "cancelled", "total": 50 },
{ "id": 3, "status": "active", "total": 175 }
]
}
The expression $.orders[?(@.status=='active')] produces two iterations: the order with id 1 and the order with id 3.
XPath Syntax Guide
XPath is used by loop:xmlPath to select elements from XML data. XPath expressions navigate the XML tree structure using path-like syntax.
Common Patterns
| XPath Expression | Description |
|---|---|
//order | All order elements anywhere in the document |
/root/items/item | item elements at the specific path /root/items/item |
//item[@status='active'] | item elements with a status attribute equal to active |
//product[price > 100] | product elements where the child price element value is greater than 100 |
//customer/name | The name child element of every customer element |
//order[1] | The first order element (XPath indices start at 1) |
//order[last()] | The last order element |
//order[position() <= 5] | The first 5 order elements |
//item[@category='electronics' and @inStock='true'] | Items matching multiple attribute conditions |
//div[contains(@class, 'result')] | Elements whose class attribute contains result |
Path Syntax
/-- selects from the root node (absolute path)//-- selects matching nodes anywhere in the document (recursive)@-- selects an attribute[]-- predicate filtertext()-- selects the text content of an element
Example input and expression:
Given this XML data:
<root>
<items>
<item status="active"><name>Widget A</name><price>25</price></item>
<item status="inactive"><name>Widget B</name><price>15</price></item>
<item status="active"><name>Widget C</name><price>40</price></item>
</items>
</root>
The expression //item[@status='active'] produces two iterations: Widget A and Widget C.
Loop Variables and Step References
Accessing the Current Item and Index
Inside a loop body, each iteration exposes variables that you can reference in step parameters:
- Item variable: The current element is available via the name specified in
itemVariable(defaults toloopItem). Reference it in step parameters asloopItemor whatever custom name you specified. - Index variable: The current zero-based index is available via the name specified in
indexVariable(defaults toloopIndex).
After the Loop Completes
When the loop finishes, only the last iteration's step outputs remain accessible via standard step references. Earlier iterations' outputs are overwritten.
To accumulate results across all iterations, use one of these approaches:
- Variables node: Inside the loop body, add a Variables node step that appends each iteration's result to an array variable. After the loop, the array contains all results.
- Evaluate node: Use an Evaluate node inside the loop to build up a collection in a variable.
Example: Building a summary list
Step 1: API node → fetch list of customers → output: customerList
Step 2: Loop:variable → variable: customerList, itemVariable: customer
Step 2a: API node → fetch details for current customer
Step 2b: Variables node → append customer summary to "allSummaries" array
Step 3: Email node → send allSummaries as a report
Performance and Memory Guidance
Each loop iteration executes the full set of loop body steps as a sub-workflow. This has implications for performance and resource usage.
Execution Time
- Each iteration incurs the overhead of executing all loop steps sequentially.
- Large loops (1,000+ items) can significantly increase total job execution time. A loop with 10 steps that each take 1 second will take at least 10,000 seconds (nearly 3 hours) for 1,000 iterations.
Memory Usage
- All iteration results are held in memory until the loop completes.
- For very large datasets, this can cause memory pressure on the job executor.
Strategies for Large Datasets
If you need to process a large number of items, consider these approaches:
- Batching: Split the data into chunks (e.g., 100 items per batch) and run multiple loop executions. Use array slicing in JSONPath (
$.items[0:100],$.items[100:200]) or pre-process the data with an Evaluate node. - Offloading to a separate job: Use the Call node inside the loop to trigger a separate job for each item. This parallelizes execution and isolates failures.
- Pre-filtering: Reduce the number of items before entering the loop. Use JSONPath filter expressions (
$.items[?(@.status=='active')]) or an Evaluate node to remove items that do not need processing.
Safety Limits
- The
maxIterationsparameter onloop:while(default: 100) prevents infinite loops caused by conditions that never become false. - Monitor loop execution time in the execution logs. If a loop is taking longer than expected, check the iteration count and per-iteration step durations.
Common Patterns
Process Each Row from a Database Query
Use a SQL node to execute a query, then loop over the results.
Step 1: SQL node → query: "SELECT id, email FROM customers WHERE active = 1"
Step 2: Loop:variable → variable: step1.output.rows, itemVariable: row
Step 2a: Email node → to: row.email, subject: "Your monthly report"
Step 2b: SQL node → query: "UPDATE customers SET notified = 1 WHERE id = row.id"
Retry an API Call Up to N Times
Use loop:while with a condition that checks whether the previous attempt succeeded.
Step 1: Variables node → set retryCount = 0, success = false
Step 2: Loop:while → condition: success == false, maxIterations: 5
Step 2a: API node → call the target endpoint
Step 2b: Conditional node → if step2a.status == 200, set success = true
Step 2c: Variables node → increment retryCount
The loop exits when success becomes true or after 5 attempts, whichever comes first.
Parse and Process XML Elements
Use loop:xmlPath to iterate over elements in an XML response.
Step 1: API node → call SOAP service → output: xmlResponse
Step 2: Loop:xmlPath → input: xmlResponse, xpath: "//invoice"
Step 2a: Evaluate node → extract invoice fields from loopItem
Step 2b: SQL node → insert invoice record into database
Filter and Act on JSON Results
Use a JSONPath filter expression to process only matching items.
Step 1: API node → GET /api/orders → output: orderData
Step 2: Loop:jsonPath → input: orderData, jsonPath: "$.orders[?(@.amount > 1000)]"
Step 2a: Email node → send high-value order alert for loopItem
Step 2b: API node → POST /api/orders/loopItem.id/flag
Only orders with an amount greater than 1,000 are processed.
Connection
No connection required. This is a control flow node.
Output
The loop node returns metadata about the loop execution:
Each iteration's step outputs are available via the standard variable reference syntax. The last iteration's outputs remain accessible after the loop completes.