How does Restate help?
Restate makes implementing resilient sagas simple:- Durable Execution: Restate guarantees completion and automatically retries from failure points. No manual state tracking or retry logic needed
- Code-first approach: Define sagas using regular code, no DSLs required

Example
A travel booking workflow: book a flight, rent a car, then book a hotel. If any step fails (e.g. hotel full), we roll back previous steps to maintain consistency.- Wrap business logic in a try-block, throw terminal errors for compensation cases
- Add compensations to a list for each step
- In catch block, run compensations in reverse order and rethrow
defer
for compensations.
When to use Sagas
Restate automatically retries transient failures (network hiccups, temporary outages). For non-transient failures, sagas are essential:- Business logic failures: When failures are business decisions (e.g. “Hotel is full”), retrying won’t help. Throw a terminal error to trigger compensations.
- User/system cancellations: When you cancel long-running invocations, sagas undo previous operations to maintain consistency.
Running the example
1
Download the example
2
Start the Restate Server
3
Start the Service
4
Register the services
5
Send a request
6
Check the UI or service logs
See in the Restate UI (
localhost:9070
) how all steps were executed, and how the compensations were triggered because the hotel was full.
Advanced: Idempotency and compensations
Sagas in Restate are flexible and powerful since they’re implemented in user code. However, you need to make sure compensations are idempotent. The example uses customer ID for idempotency, preventing duplicate bookings on retries. The API provider deduplicates requests based on this ID. Different APIs require different approaches:- Two-phase APIs: First reserve, then confirm or cancel. Register the compensation after reservation, when you have the resource ID. This type of API usually auto-cancels reservations after a timeout.
- One-shot APIs with idempotency key: Generate idempotency key, persist in Restate, register compensation (e.g.
refund
), then do action (e.g.charge
). Register compensation first in case action succeeded but confirmation was lost.