Skip to main content
As your system grows, you’ll have workflows that make sense as standalone units — a notification sender, a company enrichment pipeline, a report generator. Child workflows let you call one workflow from another, giving each its own execution context and retry boundaries. This is an abstraction of Temporal’s child workflow execution concept.

Basic Usage

Import a workflow and call it like a regular async function:
workflow.ts
The child workflow runs with its own retry boundaries — if enrich_company fails and retries, it doesn’t affect the parent’s execution history.

Invocation Patterns

Configuration Options

The second argument to a child workflow invocation is a configuration object:

Activity Options Override

Options set on a child workflow invocation apply to all steps within that child workflow branch. Steps can still override these with their own options.activityOptions property.
Activity options are merged from broad defaults to specific overrides:
  1. Output’s default activity options
  2. The child workflow’s options.activityOptions
  3. Activity options inherited from the parent workflow
  4. The activityOptions passed to this child workflow invocation
  5. The called step’s own options.activityOptions
This lets a parent tune a child workflow branch for the current use case, while step-specific options still protect activities that need stricter behavior, such as activities that should not retry.

Lifecycle

When you call a child workflow, you have three choices: wait for it, fire it off and forget about it, or start it without waiting but let it die if the parent dies. Here’s the breakdown:

Attached (Awaited)

The parent waits for the child to finish before continuing. If the parent is terminated, the child is terminated too:
When using await, the detached flag has no effect since the parent waits for the child to complete.

Detached (Fire-and-Forget)

The parent doesn’t wait, and the child keeps running even if the parent terminates. Use this for things like sending notifications or logging — work that should finish regardless of what happens to the parent:

Not Awaited (Attached)

The parent doesn’t wait, but the child is terminated if the parent terminates. Use this when you want to kick off work in parallel but don’t need the result:

When to Use Child Workflows

Use child workflows when:
  • You have a reusable pipeline called from multiple places (e.g. enrich_company called from both lead_pipeline and account_research)
  • You want independent retry boundaries — a failing child doesn’t blow up the parent’s execution history
  • A sub-task should outlive the parent (detached mode for notifications, webhooks)
  • You’re organizing a large system into smaller, independently testable units
Don’t use child workflows when:
  • You just need to reuse a step — import the step directly
  • The logic is tightly coupled to the parent and doesn’t make sense on its own

Examples

Parallel Child Workflows

Enrich multiple companies at once by running child workflows in parallel:
workflow.ts

Fire-and-Forget Notification

Process an order and send a notification without blocking:
workflow.ts