# parallel

The `parallel` step type runs its child steps concurrently instead of one after another, with bounded concurrency, sibling dependencies, configurable failure behavior, and parent-owned output rendering. It turns independent checks, tests, and plans into a dependency-aware group that finishes faster while keeping output readable.

List the work under `steps`. Each child runs concurrently up to `max_concurrency`, and a child with a `needs` list waits for the siblings it names before it starts. Child steps must be non-interactive command steps — `shell`, `atmos`, or `sleep`.

```yaml
steps:
  - name: checks
    type: parallel
    max_concurrency: 2
    fail:
      mode: wait_all
    output:
      mode: grouped
      order: completion
      show_summary: true
      prefix: "{{ .step.name }}"
    steps:
      - name: lint
        type: shell
        command: echo "lint started"; sleep 1; echo "lint passed"

      - name: unit
        type: shell
        command: echo "unit tests started"; sleep 1; echo "unit tests passed"

      - name: package
        type: shell
        needs: [lint, unit]
        command: echo "packaging after lint and unit"
```

The [`matrix`](/workflows/steps/type/matrix) step type shares the same scheduler, failure, and output fields, but first expands a set of axes into generated child steps.

## Fields

- **`steps`**
  Required. List of child steps to run concurrently. Each child must be a 
  `shell`
  , 
  `atmos`
  , or 
  `sleep`
   step.
- **`max_concurrency`**
  Maximum number of child steps to run at once. Defaults to unbounded (all eligible children start together).
- **`fail`**
  Failure behavior for the group. See 
  [Failure behavior](#failure-behavior)
  .
- **`output`**
  How the parent renders child output. Accepts a string mode or a structured block. See 
  [Output](#output)
  .

Each child step may also declare `needs` to order it after named siblings.

- **`needs`**
  List of sibling step names that must complete successfully before this child starts. A child whose dependency fails or is skipped is itself skipped.

## Failure behavior

`fail` controls what happens when a child fails:

```yaml
fail:
  mode: wait_all       # wait_all (default) | fail_fast | best_effort
  max_failures: 0      # 0 (default) means no limit
```

- **`mode`**

  Failure mode:

  wait\_all (default): let running children finish, skip dependents of failed children, then fail the parent if any child failed.
  fail\_fast: cancel pending and running children as soon as the failure threshold is reached.
  best\_effort: record failures but let the parent succeed.
- **`max_failures`**
  Number of child failures tolerated before 
  `fail_fast`
   cancels the group. 
  `0`
   (default) means no limit.

## Output

The parent step owns rendering for the whole group so concurrent output stays readable. Set `output` to a string for the mode, or to a block for full control:

```yaml
output:
  mode: grouped        # grouped (default) | prefixed | none
  order: completion    # completion | definition (grouped only)
  show_summary: true   # print the success/failed/skipped/canceled summary
  prefix: "{{ .step.name }}"
```

- **`mode`**

  Rendering mode:

  grouped (default): capture each child's output and print it in a labeled block once the child finishes.
  prefixed: stream child output live, prefixing every line with the child's label.
  none: suppress child output.
- **`order`**
  For 
  `grouped`
   mode, the order blocks are printed: 
  `completion`
   (as children finish) or 
  `definition`
   (in declared order).
- **`show_summary`**
  Print a summary line with success, failed, skipped, and canceled counts after the group completes.
- **`prefix`**
  Go template for the per-child label, evaluated with the child step context (for example 
  `{{ .step.name }}`
  ).

## Example

A runnable example lives in [`examples/parallel-steps`](https://github.com/cloudposse/atmos/tree/main/examples/parallel-steps):

```shell
atmos workflow checks -f parallel
```
