Execution controls
Use a looping strategy to run a stage or step multiple times; iterate a fixed number of times with a for loop, loop conditionally with a while loop, or fan out across input combinations with a matrix.
A strategy tells Harness to run a stage or step more than once. Instead of duplicating stages or steps for each environment, region, or input combination, you define the variation once and let the strategy expand it at runtime.
Strategy can be applied at the stage level (each instance runs as a separate stage) or the step level (each instance runs as a separate step within the same stage).
What you will learn
How to use for loop, while loop, and matrix strategies to run a stage or step multiple times
How matrix fans out across combinations of values and how to reference axis values in steps
How to exclude specific matrix combinations and customize instance names with
node-nameHow
max-parallelandfail-fastcontrol strategy execution behavior
The Strategy panel has three shared settings that apply to all strategy types:
Max parallel
Maximum number of strategy instances that run simultaneously. Set to 0 for unlimited (default).
Fail fast
When true, cancels all running instances if any one instance fails.
Strategy type
The looping type: For loop, While loop, or Matrix.
For loop
A for loop runs the stage a fixed number of times. Each iteration runs as a separate stage instance. By default, all instances run in parallel.
stages:
- name: build
id: build
strategy:
max-parallel: 0
fail-fast: true
for:
iterations: 3
steps:
- name: run
id: run
run:
script: |
echo "Iteration: ${{ strategy.iteration }}"
echo "Total: ${{ strategy.iterations }}"Verified expression output for 2 iterations:
${{ strategy.iteration }}
Current iteration index (0-based): 0, 1
${{ strategy.iterations }}
Total number of iterations: 2
Stage naming: each instance is named <stage_id>_<index>. A stage with id: build and iterations: 3 produces build_0, build_1, build_2.
While loop
A while loop runs the stage up to a maximum number of iterations. Each iteration runs sequentially; the next instance starts only after the previous one finishes.
Stage naming follows the same pattern as for loop: poll_0, poll_1, poll_2.
Matrix
A matrix runs the stage once for every combination of values across one or more axes. All combinations run in parallel by default. The total number of instances is the product of all axis lengths minus any excluded combinations.
Basic example
This produces four instances (all 2×2 combinations):
Instance
${{ matrix.os }}
${{ matrix.node }}
test_0_0
linux
18
test_0_1
linux
20
test_1_0
windows
18
test_1_1
windows
20
Stage naming uses axis index pairs: <stage_id>_<axis1_index>_<axis2_index>.
Browser and OS testing
Run a test suite across every browser/OS combination with a concurrency cap to avoid overloading infrastructure:
Produces 9 combinations. Reference values in steps with ${{ matrix.browser }} and ${{ matrix.os }}.
JDK version matrix (single axis)
A single-axis matrix is the simplest form: run the same stage once for each value in a list. With max-parallel set, instances beyond the cap queue until a slot opens:
Reference the current JDK version with ${{ matrix.jdk }}. Single-axis instances are named <stage_id>_0, <stage_id>_1, <stage_id>_2 (not _0_0 like multi-axis).
Service × environment deployment
Deploy multiple services to multiple environments, with a specific combination excluded:
This produces 5 instances (3×2 = 6, minus 1 excluded). Reference with ${{ matrix.service }} and ${{ matrix.environment }}.
Exclude combinations
Exclude a specific pair:
Exclude all combinations containing a value (omit one key to match any pairing):
This removes all three macos combinations, producing 6 instances instead of 9.
Custom instance names with node-name
By default, instances are named <stage_id>_0_0, <stage_id>_0_1, etc. Use node-name to give instances meaningful names:
This produces stage identifiers: deploy_api_staging, deploy_worker_staging, deploy_api_production, deploy_worker_production.
Comparison
Input
Integer count
Integer count
One or more value lists
Default execution
Parallel
Sequential
Parallel
Stage naming
<id>_0, <id>_1
<id>_0, <id>_1
<id>_0_0, <id>_0_1
Current value expression
${{ strategy.iteration }}
${{ strategy.iteration }}
${{ matrix.<axis> }}
Next steps
Go to Concurrency to limit parallel instances with
max-parallel.Go to Pipelines overview to review the pipeline model.
Last updated
Was this helpful?