Counting visitors…
Browse all docs
Start · 9Find your path through RunifoldLearn Runifold in 45 minutesUnderstand the complete Runifold platformYour first trustworthy runChoose the right execution APIChoose crates and Cargo featuresBuild common Runifold applicationsRunifold frequently asked questionsTroubleshoot Runifold applications
Execution kernel · 7Understand RunContextCoordinate external effects safelyBound work with budgets and cancellationHandle errors and retries safelyEvents, journals, and execution evidenceDesign capability-safe executionRecover safely from checkpoints
Models & providers · 7Route across models without duplicate outputChoose and configure a providerUse the provider-neutral model protocolBuild on the Provider Runtime contractUse OpenAI control-plane and Realtime APIsTest and benchmark provider adaptersSet up OpenAI, Anthropic, Gemini, and Ollama
Agents · 7Build and configure an AgentGive an Agent typed toolsAdd conversations and semantic memoryDelegate to child Agents safelyReturn structured Rust valuesStream without losing semanticsGround an Agent with retrieval
Durable workflows · 7Compose deterministic workflowsMake workflows durableOperate durable workflow workersCoordinate timers, signals, and durable waitsRun multi-tenant workflow infrastructureRun parallel branches and safe racesVersion and evolve durable workflows
Integrations · 7Connect through MCPChoose stores and persistence boundariesExpose durable work through MCP TasksBuild and evaluate retrieval pipelinesUse MCP Resources, Prompts, and SamplingCache MCP responses without crossing authorityDeploy Runifold in a Rust web service
Quality & operations · 10Test without the networkEvaluate quality and prevent regressionsObserve the complete run treeRun safely in browsers and at the edgeRead reliability claims preciselyRun reproducible evaluations in CIOperate Runifold with SLOsGovern Task retention and deletionArchive audit evidence to S3-compatible WORM storageManage compatibility and trusted releases
Docs/Durable workflows
NEW TO RUNIFOLD?Build the complete mental model in 45 minutes
Durable workflows

Run parallel branches and safe races

Reserve shared budgets, persist branch progress, join deterministically, fail fast, and race only side-effect-safe work.

Practical guide·12 min

Parallel contract

Parallel workflow execution is a governed fan-out/fan-in node, not a collection of detached futures. Every uniquely named ParallelBranch receives the same canonical input, an attenuated Capability Set, a reserved budget share, and a child Run.

All branches must be admitted before any starts. Joined output is keyed by stable Step identity, so completion timing never changes output order.

Budget reservations

Atomic counters alone let the fastest branch spend the whole remaining budget. Batch reservation assigns deterministic maximum ownership to every sibling. The batch is all-or-nothing; a scoped tracker cannot consume another branch's share.

Consumption becomes committed Run usage. Dropping the final scoped reservation releases unused capacity. Choose reservations as tolerated maximums, not optimistic averages.

Durable branch state

Checkpoint state records every branch as in-flight, completed with output, or failed. Successful outputs persist independently. Recovery never reruns a completed branch; incomplete work requires explicit retry authority.

Fail-fast parallelism records the failing branch and cancels unfinished siblings. Cancellation is cooperative and does not prove a remote call stopped or undo an Effect.

First-success race

A Race returns the first successful canonical output, but accepts only Pure and ReadOnly capabilities. Idempotent writes are still rejected: idempotency avoids duplicate writes, not unwanted writes from losing branches.

Every branch is polled once before a winner can be accepted. Losers are cancelled and their unused reservations are conservatively forfeited because remote usage may continue without a terminal event.

Choose a policy

Use parallel fan-out when every result is required. Use Race for redundant read-only routes where latency matters and worst-case losing cost is acceptable. Use sequential fallback when a first route can fail safely before the next begins. Avoid concurrency when external writes need deterministic ordering.

Document branch authority, reservation, failure policy, checkpoint behavior, and reconciliation before production.

Build a bounded parallel node

let per_branch = Usage { turns: 1, ..Usage::default() };
let workflow = Workflow::builder("parallel-analysis")
    .parallel("analyze", [
        ParallelBranch::step(
            "risk", RiskStep, CapabilitySet::new(), per_branch,
        ),
        ParallelBranch::step(
            "value", ValueStep, CapabilitySet::new(), per_branch,
        ),
    ])
    .build()?;
 
let run = RunContext::root(
    BudgetTracker::new(Budget { turns: Some(2), ..Budget::default() }),
    CapabilitySet::new(),
);
let outcome = workflow.run("proposal", &run).await?;

The joined JSON object is keyed by stable branch ID, independent of completion order. The parent budget must admit every reservation before any branch starts. For race(...), use the same shape but grant only Pure or ReadOnly capabilities; the builder rejects write-capable branches.