Steps inside this pattern inherit the same
max_retries, guardrails, and output_file policies as top-level steps. See Nested workflows → Retry, guardrails, and output_file.As of PraisonAI #4932, an
output_variable set inside a branch is preserved after the parallel block. Earlier releases silently discarded it.Quick Start
1
Define parallel workers
2
Run parallel workflow
API Reference
parallel()
Parameters
Accessing Results
After parallel execution, results are available inctx.variables:
Index alignment under
partial_ok. A failed branch contributes None at the same index as its step, so parallel_outputs[i] is always the result of parallel_step.steps[i]. As of PraisonAI #4203, a downstream reader of parallel_outputs[i] can no longer silently receive a later branch’s result once an earlier branch fails.Named outputs from branches
Every step insideparallel([...]) may set output_variable. As of PraisonAI #4932, that write is visible to any step after the parallel block, keyed by that exact name — not just as a positional entry in parallel_outputs.
output_variable is stored under that exact name; the ordered parallel_outputs list is still there for aggregators that want positional access.
Each branch runs against its own deep copy of the variables, so branches never race on one shared dict. After the block, only the keys a branch actually wrote merge back into the shared scope — untouched variables keep the parent’s own object.
Two branches wrote the same variable
When two branches write the sameoutput_variable, declaration order wins — the later branch overwrites the earlier, matching what running the same steps sequentially would produce. The result never depends on which thread finishes first.
WARNING names the key and both branches. Silent last-writer-wins was the exact bug #4932 removes, so a collision is reported rather than hidden.
Examples
With Agents
Mixed Steps
Nested Parallel
Performance
Parallel execution uses Python’sThreadPoolExecutor:
- Concurrent I/O: Ideal for API calls, file operations
- Thread-safe: Each step gets its own copy of variables
- Automatic joining: All results collected before next step
Use Cases
How It Works
Best Practices
Parallelise only independent steps
Parallelise only independent steps
Branches must not depend on each other’s output in the same parallel group.
Cap concurrency for external APIs
Cap concurrency for external APIs
Rate-limited tools may need sequential execution or throttling despite parallel support.
Collect and inspect branch errors
Collect and inspect branch errors
Read the aggregated error list after
ParallelExecutionError before retrying.Keep branch outputs small
Keep branch outputs small
Large parallel results inflate context — summarise before merging downstream.
Give sibling branches distinct output_variable names
Give sibling branches distinct output_variable names
Two branches writing the same
output_variable collide — the later-declared branch silently overwrites the earlier one (with a warning). That class of silent loss is exactly what #4932 fixes; distinct names (branch_a_score, branch_b_score) avoid it entirely.Failure Handling
Choose how a parallel block reacts when a branch fails using theon_failure parameter.
Failure Strategies
Variable merging on failure. Under
partial_ok, the variables a failed branch had already written before it failed are preserved — its own output_variable is never set (the failure path returns before that write), so a downstream reader cannot pick up a value the failure invented. Under fail_fast / fail_all, nothing from any branch is merged: the block raises before the merge runs. See Named outputs from branches.Examples
Error Handling with partial_ok
Stop propagation from nested steps
A branch step withon_error="stop" halts the whole workflow, not just the parallel block — even under on_failure="partial_ok". As of PraisonAI #4203, parallel(...) propagates a nested stop up to the enclosing workflow, matching route() / loop() / repeat() / if_().
on_failure mode and a branch step’s on_error is:
Exception Handling with fail_fast/fail_all
Related
Workflow Patterns
Overview of routing, parallel, loop, and repeat
Workflow Routing
Decision-based branching
Workflow Loop
Iterate over lists and files
Workflow Repeat
Repeat until a condition is met

