Workflows orchestrate complex business processes that span multiple steps, services, and time periods. Restate workflows are written as regular functions in your programming language, with automatic durability, state management, and event handling built in. In this guide, you’ll learn how to:
  • Write workflows as regular functions with automatic durability
  • Handle long-running processes with state and event patterns
  • Deploy steps inline or services that can scale independently
  • Build resilient, observable workflows without external dependencies
Select your SDK:

Getting Started

A Restate application is composed of two main components:
  • Restate Server: The core engine that manages durable execution and orchestrates services. It acts as a message broker or reverse proxy in front of your services.
  • Your Services: Your workflows and business logic, implemented as service handlers using the Restate SDK to perform durable operations.
Application Structure A basic signup workflow looks like this: A workflow has handlers that can be called over HTTP. The run handler is the main entry point that executes the workflow logic. An execution of the workflow is identified by a unique key (in this case, the user ID) and uses Restate’s WorkflowContext to make steps durable. You don’t need to run your services in any special way. Restate works with how you already deploy your code, whether that’s in Docker, on Kubernetes, or via AWS Lambda.

Run the example

Install Restate and launch it:
restate-server
This registers a set of workflows that we will be covering in this tutorial.

Submitting Workflows

The workflow can be submitted over HTTP, Kafka, programmatically, or via the UI. To submit the workflow via HTTP send the request to restate-ingress/workflow-name/key/run, in our case: Restate deduplicates workflow executions on the key, here johndoe. Resubmission of the same workflow will fail with “Previously accepted”. The invocation ID can be found in the request header x-restate-id (add -v to your request). To try out a workflow multiple times during the tour, use a different key.

Durable Execution

Restate uses Durable Execution to ensure your business logic survives any failure and resumes exactly where it left off. Unlike traditional workflow systems that require separate orchestrator infrastructure and worker management, Restate lets you deploy your workflows the same way you deploy your application code. You write a workflow as a regular function. You use the Restate SDK to persist the steps your workflow completes in the Restate Server. If your workflow crashes or restarts, the execution replays from the journal to restore state and continue processing: Durable Workflow Execution To persist a workflow step, you use the WorkflowContext actions:
  • Durable Steps: Restate’s run actions ensures non-deterministic operations like database writes or external API calls are persisted
  • Progress Recovery: If the workflow crashes after user creation, it resumes at the email step
  • Observability: Full execution traces for debugging and monitoring

In-line Steps vs. Separate Activities

Restate workflows can execute operations inline or delegate to separate services, giving you flexibility in how you structure your applications.
  • In-line Steps - Execute directly in the workflow, for example a run block.
  • Separate Activities - Call dedicated services for independent scaling, separation of concerns, or different concurrency requirements.
You can also use this to nest workflows. The main workflow can call other workflows as activities. Workflows are just one of the service types Restate supports. The other service types are:
  • Services: collections of independent handlers which get executed with Durable Execution.
  • Virtual Objects: stateful services that can be used to manage state and concurrency across multiple invocations.
To learn more, follow at the Microservice Orchestration Tour.

Workflow Patterns

Restate provides powerful patterns for building complex workflows using familiar programming constructs.

Querying Workflow State

Workflows can store state in Restate, which can be queried later by other handlers: Key characteristics:
  • State is isolated per workflow execution.
  • State lives up to the duration of the workflow retention (default one day).
  • State is queryable from other handlers or the Restate UI.
Workflow Queries

Signaling

Pause workflow execution waiting for external events using durable promises: The promise can survive restarts and crashes, and can be recovered on another process. You can use Restate’s Durable Promises to handle asynchronous events without complex message queues or external state management. Promises can be resolved before the workflow waits for them, avoiding complex synchronization issues.

Workflow Events

You can also use promises the other way around: to send events from the workflow and wait on them in one of the other handlers: Here, external clients can wait for the user to be created in the database. These handlers can be called up to the workflow’s retention period (default one day.

Timers and Scheduling

Use durable timers for long-running workflows with timeouts and retries: Because Restate lets you write workflows as regular functions, you can use your language’s native constructs like while/for loops, if statements, and switch cases to control flow. This makes it easy to implement complex logic with timers, loops, and conditional execution.

Parallel Execution

The timers example ran three operations in parallel: two timers and awaiting a promise. Restate supports different ways of waiting for parallel operations to complete and takes care of retries and recovery for you. Have a look at the Concurrent Tasks docs for your SDK to learn more (TS / Java / Kotlin / Python / Go).

Error Handling

By default, Restate retries failures infinitely with an exponential backoff strategy. For some failures, you might not want to retry or only retry a limited number of times. For these cases, Restate distinguishes between two types of errors: transient errors and terminal errors.

Transient vs Terminal Errors

  • Transient errors: These are temporary issues that can be retried, such as network timeouts or service unavailability. Restate automatically retries these errors.
  • Terminal errors: These indicate a failure that will not be retried, such as invalid input or business logic violations. Restate stops execution and allows you to handle these errors gracefully.
Throw a terminal error in your handler to indicate a terminal failure:

Configuring Retry Behavior

You can limit the number of retries of a run block: When the retries are exhausted, the run block will throw a terminal error, that you can handle in your handler logic.
Learn more with the Error Handling Guide.

Sagas and rollback

On a terminal failure, Restate stops the execution of the handler. You might, however, want to roll back the changes made by the workflow to keep your system in a consistent state. This is where Sagas come in. Sagas are a pattern for rolling back changes made by a workflow when it fails. In Restate, you can implement a saga by building a list of compensating actions for each step of the workflow. On a terminal failure, you execute them in reverse order: Benefits with Restate:
  • The list of compensations can be recovered after a crash, and Restate knows which compensations still need to be run.
  • Sagas always run till completion (success or complete rollback)
  • Full trace of all operations and compensations
  • No complex state machines needed
Learn more with the Sagas Guide.

Cancellation

You can cancel user signup workflows via HTTP, CLI, UI, or programmatically from other services. When you cancel a workflow, Restate stops the execution by throwing a Terminal Error. This allows your handler to run compensating actions or clean up resources. First, the cancellation gets propagated to the leaf nodes of the call tree (in case the workflow called other services or workflows). Then, the cancellation propagates back up the tree, allowing each handler to run its compensations.
Check out the SDK docs, to learn how to programmatically cancel a workflow from another service (TS / Java / Kotlin / Python/ Go).

Serverless Deployment

Restate lets you run your workflows and services on serverless platforms like AWS Lambda or Google Cloud Run. Restate automatically suspends workflows when they are waiting for events or timers, and resumes them when the event occurs or the timer expires. This means you can run long-running workflows on function-as-a-service platforms without paying for the wait time. Turning your signup workflow into a serverless function is as simple as adapting the endpoint:

Summary

Restate workflows provide:
  • Natural Programming: Write workflows as regular functions in your preferred language
  • Automatic Durability: Built-in resilience without infrastructure complexity
  • Flexible Patterns: State management, events, timers, and parallel execution
  • Modern Deployment: Strong serverless support and simple single-binary deployment
With Restate, you can build complex, long-running workflows using familiar programming patterns while getting the durability you need.