Quick Start
1
Simple Usage
2
With Configuration
3
Name each branch's output
Every branch can name its result with
output_variable; the write survives the block and is readable by any later step.How It Works
Configuration Options
parallel() accepts a list of agents or step callables. Each worker receives the same workflow context; results are collected in ctx.variables["parallel_outputs"] for the next step.
Best Practices
Keep parallel tasks independent
Keep parallel tasks independent
Only parallelise work that does not need another worker’s output mid-flight. Route dependent steps after the aggregator.
Use an aggregator for synthesis
Use an aggregator for synthesis
A dedicated agent (or function step) after
parallel() turns multiple raw outputs into one coherent response.Prefer astart for I/O-heavy workers
Prefer astart for I/O-heavy workers
When workers call external APIs, use
await workflow.astart() so concurrent I/O does not block the event loop.Watch rate limits
Watch rate limits
Parallel LLM calls multiply token usage and API requests. Cap worker count or add a rate limiter if needed.
Prefer named outputs over positional aggregation when order matters
Prefer named outputs over positional aggregation when order matters
Name each branch’s result with
output_variable and read it by name downstream, rather than relying on the position of parallel_outputs. See Named outputs from branches.Related
Orchestrator Worker
Route tasks to specialised workers from a central orchestrator
AgentFlow
Build multi-step agent pipelines

