
duroxide
Latest Release: v0.1.30 — Sub-orchestration parent-link and collision fixes, safer IDs, and UUID generation. See CHANGELOG.md for release notes.
Preview: This project is currently in preview.
Duroxide is a lightweight, embeddable durable execution runtime for Rust.
Write ordinary async Rust. Duroxide makes it durable: your code keeps
running across process crashes, restarts, and deployments. A workflow that
waits 30 days looks exactly like one that waits 30 milliseconds — and if the
process dies in the middle, it resumes right where it left off, without
re-running the work it already finished.
Inspired by the Durable Task Framework and Temporal.
What you get
- Durable by default — every step is recorded; crashes resume from the last completed step.
- Plain async Rust — orchestrate with
.await, control flow, and error handling you already know. - Embeddable — runs in-process on Tokio. No separate server to operate.
- Storage-agnostic — a
Providertrait backs persistence; a SQLite provider (in-memory or file) is built in.
What you can build
- Function chaining — sequential steps where each depends on the last.
- Fan-out / fan-in — run many activities in parallel, then aggregate deterministically.
- Human-in-the-loop — wait for approvals, callbacks, or webhooks, then resume.
- Durable timers — sleep for minutes, hours, or days without holding a thread.
- Saga compensation — roll back prior steps on failure.
- Built-in retries — configurable backoff and per-attempt timeouts.
- Cancellation — in-flight activities receive cooperative cancellation signals.
- Worker specialization — route activities to dedicated pools with tags (e.g.
gpu). - Durable KV — per-instance key/value state that survives replay.
Install
[]
= { = "0.1", = ["sqlite"] } # With the bundled SQLite provider
# OR
= "0.1" # Core only — bring your own Provider
Examples
Hello world
use Arc;
use ;
use ;
use ActivityRegistry;
use SqliteProvider;
#
# async
Surviving crashes
Each completed step is durably recorded, so a restart replays history and resumes from exactly where it stopped.
use OrchestrationContext;
async
Fan-out / fan-in
use OrchestrationContext;
async
Timers and external events
use ;
async
Error handling and compensation
use OrchestrationContext;
async
How it works
Duroxide runs each orchestration turn by turn. Every operation gets a
correlation id; scheduling is recorded as a history event (e.g.
ActivityScheduled) and completions are matched back by id (e.g.
ActivityCompleted). On restart, the runtime replays that history to
rebuild in-memory state: completed steps return their recorded results without
re-executing, and the orchestration continues from the first unfinished step.
This is why orchestrations must be deterministic — they coordinate, they don't do I/O. Activities are where side effects happen, and they run at most once per logical step. A few consequences worth knowing:
- Use
ctx.join/ctx.select2(nottokio::join!/tokio::select!) so concurrency resolves by history order, not wall-clock polling. - Use
ctx.schedule_timer(),ctx.new_guid(),ctx.utcnow()instead ofstd::time,rand, orUuid::new_v4()directly.
📖 For the full story — how futures are made durable, the replay algorithm step by step, and nondeterminism detection — read Durable Futures Internals.
The Duroxide family
Several related projects share Duroxide's durable-execution model. Pick the one that fits how you want to author and host your workflows:
- pg_durable — PostgreSQL extension. Use this when you want durable pipelines and functions directly in PostgreSQL, with no other moving parts.
- duroxide (this repo) — Rust durable-execution runtime. Use this when you want to author workflows in Rust and embed the runtime in your service. Multiple storage providers are available (SQLite built-in, PostgreSQL via duroxide-pg, or bring your own).
- duroxide-python — Python SDK over the duroxide runtime. Use this when you want to author workflows in Python.
- duroxide-node — Node.js / TypeScript SDK over the duroxide runtime. Use this when you want to author workflows in JavaScript / TypeScript.
- duroxide-pg — PostgreSQL provider for the duroxide runtime. Plug this into duroxide / duroxide-python / duroxide-node when you want PostgreSQL as the durable store.
Learn more
- Orchestration Guide — the complete guide to writing workflows.
- Durable Futures Internals — how replay and durability work under the hood.
- Provider Implementation / Provider Testing — build and test a custom storage backend.
- Observability Guide — structured logging and metrics.
- AI Skills — context files for AI assistants (Copilot, Cursor, etc.).
- Examples —
cargo run --example hello_world, plus more inexamples/andtests/e2e_samples.rs.
Development
See CHANGELOG.md for release notes and CONTRIBUTING.md to get involved.
Support
Use GitHub Issues for bug reports and feature requests. Do not report security vulnerabilities through public GitHub issues; follow the instructions in SECURITY.md instead.
Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact opencode@microsoft.com with questions or comments.
Security
Microsoft takes the security of our software products and services seriously. Please do not report security vulnerabilities through public GitHub issues. See SECURITY.md for security reporting instructions.
Privacy and Telemetry
Duroxide does not send telemetry to Microsoft. Applications may configure their own logging or metrics exporters; those signals are controlled by the application owner.
Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos is subject to those third-party policies.
License
MIT License - see LICENSE for details.