Fully Open
Durable Execution

Use any database or queue for storage and message transport. Then just write Async Await.

An SDK in your app, one binary beside it.

Server · SDKs — all Apache 2.0

same app, any stackopen protocol
your codenever changes

await ctx.run(chargeCard, order)

Async Await · any Resonate SDK

the serverApache 2.0
resonate on Postgresone binary
storage

Postgres

the database or queue you already run

transport

HTTP

the transport you already use

A new server for every stack — that’s Distributed Async Await working. Run something else? Bring your own provider.

Durable execution, now on NATS and ScyllaDB

The reliability tax

You write retries, timeouts, and a recovery branch. Then you write the feature.

In a production system, the code that does the actual work is the small part. The rest keeps it alive when something goes wrong — retries, timeouts, idempotency keys, the state machines that remember where a job was when the process died.

By most counts that defensive scaffolding is more than two-thirds of what you ship — and almost none of it is the product. It doesn’t have to be yours to write.

your_program.tswhat you ship

// the product — the actual work

handleOrder()the thing your users came for

// keeping it alive when something goes wrong

retry()
timeout()
idempotencyKey()
stateMachine()
checkpoint()
resumeFrom()
~⅔of what you ship, by most counts.

Simple to use

You already know how to write this.

You write ordinary async functions, and that Async Await is the workflow — the shape of your code is the shape of the execution.

Most of what you’ll write rests on three verbs. A workflow that runs forever is a while loop.

// the common surface
ctx.run(step)      // execute a step durably
ctx.rpc(fn)        // call another function
ctx.sleep('30d')   // wait — a second or a month

…and ctx.detached when you want to kick something off and not wait on it.

Simple to reason about

Everything comes down to one promise.

The primitive is a durable promise. Everything your code waits on resolves to one — written down the moment it’s made and settled when it’s done.

The promise lives outside the process that made it, in storage you run, so when that machine crashes a new process reads the last promise that was kept and picks up from there.

process running
the promise · sustainedthe process · crashes & restarts

Runs on your infrastructure

It runs on what you already run.

The core server is a single binary. It runs alongside the rest of your stack, and its state lives in your own Postgres — the database you already know how to run and back up. On NATS, an implementation of the protocol runs natively on the broker itself.

When you want to know what a workflow is doing, you ask the CLI. resonate tree prints the whole call graph; resonate promises get inspects a single step. Underneath, the state is rows in your own Postgres, and you can read it with plain SQL.

your stack

▢ resonate — one binary

└─ state → your Postgres

$ resonate tree order/42

A promise is written once and updated when it completes, not on every step. The cost of a workflow follows how much it does.

An open protocol

The specification is public. Anyone can implement it.

Durable execution is a protocol. Resonate is an implementation of it, open source under Apache 2.0, and you adopt it the way you adopt HTTP or SQL. The servers on NATS and ScyllaDB are separate implementations of the same protocol, source-available under BUSL 1.1.

You can run Resonate, read it, fork it, or build your own. The implementation is tested against the specification — differential testing, deterministic simulation, linearizability checks: how Resonate is tested.

distributed-async-await.io ↗

the open specification — programming, execution & system models

Server and SDKs, all open sourceFork or build your ownA growing library of agent skills
Discord — people building right now