Skip to main content

Workflows-as-code

Lightweight, flexible, durable.

Combine the resiliency of workflows with the speed and flexibility of regular functions. Restate orchestrates and manages their execution till completion, whether it’s millis or months.

Workflows-as-code

Familiar programming model
Restate gives workflow semantics to any function: retries, recovery of progress,... Restate provides a distributed, durable version of familiar building blocks: timers, promises, signals,...
Low latency
Restate is built from the ground up to serve low-latency workflows. You can now put workflows in the latency-sensitive path of user interactions.
Support for serverless
Run your workflow and/or its activities on Function-as-a-Service platforms. Restate lets your functions suspend whenever they wait on inputs.

Workflows with Restate

Use Restate's durable building blocks to implement workflows that are resilient to failures and recoverable.

Durable building blocks

The Restate SDK gives you access to durable building blocks that you can use to build workflows: RPC calls, events, timers, promises, signals, and more.

Learn more

Durable building blocks

The Restate SDK gives you access to durable building blocks that you can use to build workflows: RPC calls, events, timers, promises, signals, and more.

Learn more

Persist progress

Restate logs the progress your code makes and recovers it in case of a crash. This way, you can build workflows that are durable and resilient to failures.

Learn more

Persist progress

Restate logs the progress your code makes and recovers it in case of a crash. This way, you can build workflows that are durable and resilient to failures.

Learn more

Durable promises and signals

Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.

Durable promises and signals

Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.

const signupWorkflow = restate.workflow({
name: "user-signup",
handlers: {
run: async (
ctx: restate.WorkflowContext,
user: { name: string; email: string },
) => {
// workflow ID = user ID; workflow runs once per user
const userId = ctx.key;
await ctx.run(() => createUserEntry(user));
const secret = ctx.rand.uuidv4();
await ctx.run(() => sendEmailWithLink({ userId, user, secret }));
const clickSecret = await ctx.promise<string>("link-clicked");
return clickSecret === secret;
},
click: async (
ctx: restate.WorkflowSharedContext,
request: { secret: string },
) => {
await ctx.promise<string>("link-clicked").resolve(request.secret);
},
},
});

Workflows as regular, lightweight functions

Restate is a single binary and its workflow functionality is integrated in its core.
Your workflows run like any other function in your infrastructure: on K8S, FaaS, or mix-and-match.
No need to spin up extra infrastructure or dedicated workers.

Workflows as regular, lightweight functions

Invoke idempotently and latch on

A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.

If the caller loses the connection to the workflow, he can latch on again to retrieve the result.

// import * as clients from "@restatedev/restate-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
await restateClient
.workflowClient<SignUpWorkflow>({ name: "user-signup" }, user.id)
.workflowSubmit(user);
// do something else, with workflow running in the background
// attach back to the workflow
const result = await restateClient
.workflowClient<SignUpWorkflow>({ name: "user-signup" }, user.id)
.workflowAttach();
LOW-LATENCY

Restate’s event-driven foundation built in Rust lets you put workflows in the latency-sensitive path of user interaction.

Learn more

DURABLE EXECUTION

Restate handles retries and recovers your code to the exact point before the crash. State changes take part in durable execution, so the state never gets out of sync.

Learn more

Flexible, Stateful Workflows with Restate

Flexible logic and failure handling

Restate guarantees code runs to completion. This makes it easy to implement resilient sagas in a simple try-catch block.

Track all rollback actions in a list and run them on unrecoverable failures.

Restate takes care of retries and recovery and makes sure all compensations run.

Learn more

Flexible logic and failure handling

Restate guarantees code runs to completion. This makes it easy to implement resilient sagas in a simple try-catch block.

Track all rollback actions in a list and run them on unrecoverable failures.

Restate takes care of retries and recovery and makes sure all compensations run.

Learn more

Queryable workflow state

Use Restate’s built-in key-value store to store workflow state. Restate guarantees that it is consistent and persistent, since state updates are tracked together with the rest of the execution progress.

You can retrieve the current state of the workflow from within other handlers and expose it to external clients.

Queryable workflow state

Use Restate’s built-in key-value store to store workflow state. Restate guarantees that it is consistent and persistent, since state updates are tracked together with the rest of the execution progress.

You can retrieve the current state of the workflow from within other handlers and expose it to external clients.

Stateful, serverless workflows

You can run stateful workflows on serverless infrastructure, like AWS Lambda. Restate attaches the state to the request. Your handlers work on local state

Learn more

Stateful, serverless workflows

You can run stateful workflows on serverless infrastructure, like AWS Lambda. Restate attaches the state to the request. Your handlers work on local state

Learn more

const subscriptionWorkflow = restate.workflow({
name: "SubscriptionWorkflow",
handlers: {
run: async (ctx: restate.WorkflowContext, req: SubscriptionRequest) => {
const compensations = [];
try {
const paymentId = ctx.rand.uuidv4();
compensations.push(() => removeRecurringPayment(paymentId))
await ctx.run(() => createRecurringPayment(req.creditCard, paymentId));
ctx.set("status", "payment_success");
for (const subscription of req.subscriptions) {
compensations.push(() => removeSubscription(req.userId, subscription))
await ctx.run(() => createSubscription(req.userId, subscription));
}
ctx.set("status", "subscribed");
} catch (e) {
if (e instanceof restate.TerminalError) {
for (const compensation of compensations.reverse()) {
await ctx.run(() => compensation());
}
ctx.set("status", "rolled_back");
}
throw e;
}
},
},
})
export const awsLambdaHandler = restate
.endpoint()
.bind(subscriptionWorkflow)
.handler();

Detailed Observability

Understand what is happening in your workflows, by using the UI, the CLI, and the built-in tracing.
Debug failing workflows, inspect the K/V state, and manage deployments.

Detailed Observability
What can you do with UI?What can you do with CLI?

What you can build with Workflows and Restate

User sign-up workflow

Create user in the system, wait until email confirmation, schedule a reminder, send welcome email, etc.

Order processing and logistics

Handle the payment, request the order preparation, wait for driver acceptance callback, etc.

Infrastructure provisioning

Go through a set of steps to provision a setup. Retry until resources are up, handle timeouts, rollbacks, etc.

Workflow interpreters and AI agents

Dynamically compose workflows based on user input. For example, an image transformer that lets users specify the steps to be taken.

AI workflows

An ingestion workflow to make documents available for RAG.

Wondering about a specific use case?

Let’s brainstorm together on Discord or Slack.

Developer Resources

Blog post

The simplest way to write workflows-as-code.

Docs

Read the docs to learn more.

Need help?

Join the Restate Discord or Slack communities