- TypeScript
- Java
- Kotlin
- Python
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.
Just code
Low latency
Deploy on FaaS
Workflows with Restate
Implement the run
function of your workflow, using the Restate SDK.
- TypeScript
- Java
- Kotlin
- Python
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
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.
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.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
const signUpWorkflow = restate.workflow({name: "sign-up-workflow",handlers: {run: async (ctx: WorkflowContext, user: User) => {const { id, name, email } = user;ctx.set("stage", "Creating User");await ctx.run(() => createUserEntry({ id, name }));ctx.set("stage", "Email Verification");const secret = ctx.rand.uuidv4();await ctx.run(() => sendEmailWithLink({ email, secret }));const clickSecret = await ctx.promise<string>("email-link");if (clickSecret !== secret) {ctx.set("stage", `Verification failed`);throw new TerminalError("Wrong secret from email link");}ctx.set("stage", "User verified");return true;},getStage: (ctx: WorkflowSharedContext) => ctx.get("stage"),approveEmail: (ctx: WorkflowSharedContext, secret: string) =>ctx.promise<string>("email-link").resolve(secret)},});
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
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.
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.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
@Workflowpublic class SignupWorkflow {private final StateKey<String> STAGE = StateKey.of("stage", JsonSerdes.STRING);private final DurablePromiseKey<String> EMAIL_LINK =DurablePromiseKey.of("email-link", JsonSerdes.STRING);@Workflowpublic boolean run(WorkflowContext ctx, User user) {ctx.set(STAGE, "Creating user");ctx.run(() -> createUserEntry(ctx.key(), user.getName()));ctx.set(STAGE, "Email verification");String secret = ctx.random().nextUUID().toString();ctx.run(() -> sendEmailWithLink(user.getEmail(), secret));String clickSecret = ctx.promise(EMAIL_LINK).awaitable().await();if (!clickSecret.equals(secret)) {ctx.set(STAGE, "Verification failed");throw new TerminalException("Wrong secret from email link");}ctx.set(STAGE, "User verified");return true;}@Handlerpublic String getStage(SharedWorkflowContext ctx) {return ctx.get(STAGE).orElse("Unknown");}@Handlerpublic void approveEmail(SharedWorkflowContext ctx, String secret) {ctx.promiseHandle(EMAIL_LINK).resolve(secret);}}
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
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.
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.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
@Workflowclass SignupWorkflow {companion object {private val STAGE = KtStateKey.json<String>("stage")private val EMAIL_LINK = KtDurablePromiseKey.json<String>("email-link")}@Workflowsuspend fun run(ctx: WorkflowContext, user: User): Boolean {ctx.set(STAGE, "Creating user")ctx.runBlock { createUserEntry(ctx.key(), user.name) }ctx.set(STAGE, "Email verification")val secret = ctx.random().nextUUID().toString()ctx.runBlock { sendEmailWithLink(user.email, secret) }val clickSecret = ctx.promise(EMAIL_LINK).awaitable().await()if (clickSecret != secret) {ctx.set(STAGE, "Verification failed")throw TerminalException("Wrong secret from email link")}ctx.set(STAGE, "User verified")return true}@Handlersuspend fun getStage(ctx: SharedWorkflowContext): String? {return ctx.get(STAGE)}@Handlersuspend fun approveEmail(ctx: SharedWorkflowContext, secret: String) {ctx.promiseHandle(EMAIL_LINK).resolve(secret)}}
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Run once, idempotently
A workflow runs exactly one time. Restate makes sure that duplicate requests do not lead to duplicate execution.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
Persist progress
Store results of intermediate steps, interaction with external systems, or non-deterministic actions. Restate makes sure that on retries, the code does not get re-executed and the previous result is returned. This lets you execute the steps of your workflows durably.
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.
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.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Query workflow state
Retrieve the current state of the workflow from within other handlers and expose it to external clients.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Wait on external signals
Make Promises/Futures resilient by registering them in Restate. Share them and wait until other functions resolve them.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Signal in-flight workflows
Notify the workflow of external signals, callbacks or Kafka events. Resolve or reject shared promises on which the workflow is waiting. The workflow handles the outcome.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
Flexible failure handling
Implement sagas and compensations in code, as per your requirements.
signup_workflow = Workflow("signupWorkflow")@signup_workflow.main()async def run(ctx: WorkflowContext, user: User) -> bool:ctx.set("stage", "Creating user")await ctx.run("create user", lambda: create_user_entry(user))ctx.set("stage", "Email verification")secret = await ctx.run("generate secret", lambda: str(uuid.uuid4()))await ctx.run("send email", lambda: send_email_with_link(user.email, secret))click_secret = await ctx.promise("email_link_clicked").value()if click_secret != secret:ctx.set("stage", "Email verification failed")raise TerminalError("Wrong secret from email link")ctx.set("stage", "Email verified")return True@signup_workflow.handler("getStage")async def get_stage(ctx: WorkflowSharedContext) -> str:return await ctx.get("stage") or "unknown"@signup_workflow.handler("approveEmail")async def approve_email(ctx: WorkflowSharedContext, secret: str):await ctx.promise("email_link_clicked").resolve(secret)
LOW-LATENCY
Restate’s event-driven foundation built in Rust lets you put workflows in the latency-sensitive path of user interaction.
DURABLE EXECUTION
Restate handles retries and recovers your code to the exact point before the crash. No more coarse per-step retries. State changes take part in durable execution, so the state never gets out of sync.
- TypeScript
- Java
- Kotlin
- Python
Latch on to a workflow
A workflow runs exactly one time. 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 rs = clients.connect({ url: "http://localhost:8080" });await rs.workflowClient<SignUpWorkflow>({ name: "sign-up-workflow" }, user.id).workflowSubmit(user);// do something else, with workflow running in the background// attach back to the workflowconst result = await rs.workflowClient<SignUpWorkflow>({ name: "sign-up-workflow" }, user.id).workflowAttach();
Latch on to a workflow
A workflow runs exactly one time. If the caller loses the connection to the workflow, he can latch on again to retrieve the result.
// import dev.restate.sdk.client.Client;Client rs = Client.connect("http://localhost:8080");SignupWorkflowClient.fromClient(rs, user.getId()).submit(user);// do something else, with workflow running in the background// attach back to the workflowboolean result =SignupWorkflowClient.fromClient(rs, user.getId()).workflowHandle().attach();
Latch on to a workflow
A workflow runs exactly one time. If the caller loses the connection to the workflow, he can latch on again to retrieve the result.
// import dev.restate.sdk.client.Client;val rs = Client.connect("http://localhost:8080")SignupWorkflowClient.fromClient(rs, user.id).submit(user)// do something else, with workflow running in the background// attach back to the workflowval result =SignupWorkflowClient.fromClient(rs, user.id).workflowHandle().attach()
Latch on to a workflow
A workflow runs exactly one time. If the caller loses the connection to the workflow, he can latch on again to retrieve the result.
import requestsrestate = "http://localhost:8080"workflow_id = "myUser123"payload = {"name": "Pete"}headers = {"Content-Type": "application/json"}# 1. Submit the workflowurl = f'${restate}/signupWorkflow/${workflow_id}/run/send'response = requests.post(url, json=payload, headers=headers)# Do something else, with workflow running in the background# 2. Attach back to the workflowattach_url = f'${restate}/restate/workflow/signupWorkflow/${workflow_id}/attach'response = requests.get(attach_url)
Workflows as regular, lightweight functions
Restate’s workflow functionality is integrated in its core.
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.
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
Dynamically compose workflows based on user input. For example, an image transformer that lets users specify the steps to be taken.