How lineage works
When a task submits a child task, UpNext automatically sets:parent_id— the job ID of the task that submitted itroot_id— the job ID of the top-level task that started the entire workflow
ContextVar, so it works across any nesting depth.
Failure propagation
When a child task fails, the exception bubbles up to the parent:TaskExecutionError in the parent, but doesn’t automatically fail the parent. This gives you full control over recovery:
Fan-out / fan-in
Submit multiple child tasks in parallel and collect results:map_tasks with concurrency control:
Multi-level workflows
Workflows can nest to any depth. Each level automatically maintains the lineage chain:root_id, so you can query the entire workflow from the dashboard or API.
Patterns
| Pattern | How | Use case |
|---|---|---|
| Sequential chain | await a.wait() then await b.wait() | ETL pipelines, ordered steps |
| Fan-out | gather(a.wait(), b.wait(), c.wait()) | Parallel data fetching |
| Fan-out with limit | map_tasks(task, inputs, concurrency=N) | Batch processing |
| Race | first_completed(a.wait(), b.wait()) | Fastest provider wins |
| Fire and forget | submit_many(task, inputs) | Bulk enqueue, collect later |
| Conditional | try/except around .wait() | Fallback on failure |
Parallel Execution
Detailed guide on gather, map_tasks, first_completed, and submit_many.
Error Handling
Configure retries and handle failures in workflows.