Skip to main content
Restate provides durable execution primitives that make distributed systems resilient by default, without the operational overhead.

Resilient Orchestration

Build microservices that automatically recover from failures without losing progress:
export const orderService = restate.service({
  name: "OrderService",
  handlers: {
    process: async (ctx: restate.Context, order: Order) => {
      // Each step is automatically durable and resumable
      const paymentId = ctx.rand.uuidv4();

      await ctx.run(() => chargePayment(order.creditCard, paymentId));

      for (const item of order.items) {
        await ctx.run(() => reserveInventory(item.id, item.quantity));
      }
      return { success: true, paymentId };
    },
  },
});
  • Automatic recovery: Code resumes exactly where it left off after failures
  • Standard development: Write services like regular HTTP APIs
  • Resilient Sagas: Implement complex multi-step transactions with resilient rollback

Reliable Communication & Idempotency

Flexible communication patterns with strong delivery guarantees: Invocations
  • Zero message loss: All service communication is durably logged
  • Built-in retries: Automatic exponential backoff for transient failures
  • Scheduling: Delay messages for future processing
  • Request deduplication: Idempotency keys prevent duplicate processing
// Request-response: Wait for result
const payRef = await ctx.serviceClient(paymentService).charge(req);

// Fire-and-forget: Guaranteed delivery without waiting
ctx.serviceSendClient(emailService).emailTicket(req);

// Delayed execution: Schedule for later
ctx
.serviceSendClient(emailService)
.sendReminder(order, sendOpts({ delay: dayBefore(req.concertDate) }));

Durable Stateful Entities

Manage stateful entities without external databases or complex consistency mechanisms: Virtual Objects
  • Durable persistence: Application state survives crashes and deployments
  • Simple concurrency model: Single-writer semantics prevent consistency issues and race conditions
  • Horizontal scaling: Each object has its own message queue. Different entity keys process independently
  • Built-in querying: Access state via UI and APIs
export default restate.object({
name: "UserAccount",
handlers: {
updateBalance: async (ctx: restate.ObjectContext, amount: number) => {
const balance = (await ctx.get<number>("balance")) ?? 0;
const newBalance = balance + amount;

if (newBalance < 0) {
throw new TerminalError("Insufficient funds");
}

ctx.set("balance", newBalance);
return newBalance;
},

getBalance: shared(async (ctx: restate.ObjectSharedContext) => {
return (await ctx.get<number>("balance")) ?? 0;
}),
},
});

Operational simplicity

Reduce infrastructure complexity (no need for queues + state stores + schedulers, etc.). A single binary including everything you need. Application Structure

Key Orchestration Patterns

Comparison with Other Solutions

FeatureRestateTraditional Orchestration
InfrastructureSingle binary deploymentMessage brokers + workflow engines + state stores
Service CommunicationBuilt-in reliable messagingExternal message queues required
State ManagementIntegrated durable stateExternal state stores + locks
Failure RecoveryAutomatic progress recoveryManual checkpoint/restart logic
Deployment ModelStandard HTTP servicesStandard HTTP services
Development ExperienceRegular code + IDE supportRegular code + IDE support
ObservabilityBuilt-in UI & execution tracingManual setup

Getting Started

Ready to build resilient microservices with Restate? Here are your next steps:
Evaluating Restate and missing a feature? Contact us on Discord or Slack.
I