DEV Community

Alex Spinov
Alex Spinov

Posted on

Restate Has a Free API: The Durable Execution Engine That Makes Distributed Systems Feel Like Local Code

Distributed systems fail in unpredictable ways. Network timeouts, partial failures, duplicate messages. Restate makes distributed code as reliable as local code — with automatic retries, state management, and exactly-once processing.

What Is Restate?

Restate is a durable execution engine. It intercepts your function calls, persists their state, and guarantees that every step completes exactly once — even across failures, restarts, and deployments. Think of it as Temporal, but lighter and easier to adopt.

The Free Platform

Restate is completely free and open source:

  • Durable execution: Functions survive crashes and restarts
  • Exactly-once: Each step executes exactly once
  • Virtual objects: Stateful entities with built-in concurrency control
  • Workflows: Long-running processes with human-in-the-loop
  • Timers: Sleep for days/weeks without consuming resources
  • SDKs: TypeScript, Java, Kotlin, Go, Rust, Python
  • Self-hosted: Single binary, no dependencies

Quick Start

Install Restate:

brew install restatedev/tap/restate-server
restate-server
Enter fullscreen mode Exit fullscreen mode

Write a durable function:

import * as restate from '@restatedev/restate-sdk';

const orderService = restate.service({
  name: 'orders',
  handlers: {
    process: async (ctx: restate.Context, order: Order) => {
      // Step 1: Reserve inventory (auto-retried on failure)
      const reserved = await ctx.run('reserve', () =>
        inventoryApi.reserve(order.items)
      );

      // Step 2: Charge payment
      const payment = await ctx.run('charge', () =>
        stripeApi.charge(order.customerId, order.total)
      );

      // Step 3: Wait for shipping (can sleep for days)
      await ctx.sleep(24 * 60 * 60 * 1000); // 24 hours

      // Step 4: Send tracking email
      await ctx.run('notify', () =>
        emailApi.sendTracking(order.email, payment.trackingId)
      );

      return { orderId: order.id, status: 'completed' };
    },
  },
});

restate.endpoint().bind(orderService).listen(9080);
Enter fullscreen mode Exit fullscreen mode

Virtual objects (stateful entities):

const counter = restate.object({
  name: 'counter',
  handlers: {
    add: async (ctx: restate.ObjectContext, value: number) => {
      // State is automatically persisted
      let count = (await ctx.get<number>('count')) ?? 0;
      count += value;
      ctx.set('count', count);
      return count;
    },
    get: async (ctx: restate.ObjectSharedContext) => {
      return (await ctx.get<number>('count')) ?? 0;
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

Call it:

# Register your service
restate deployments register http://localhost:9080

# Invoke
curl -X POST http://localhost:8080/orders/process \
  -H 'Content-Type: application/json' \
  -d '{"id": "ord_1", "items": ["item1"], "total": 4999}'
Enter fullscreen mode Exit fullscreen mode

Why Teams Choose Restate

A food delivery app had a critical bug: when their payment service timed out mid-charge, the retry logic charged customers twice. Building idempotency keys and saga patterns took months. After switching to Restate, each step is automatically idempotent and exactly-once. Double charges went from 50/week to zero.

Who Is This For?

  • Backend developers building payment flows, order processing, onboarding
  • Teams needing Temporal-like durability without the operational complexity
  • Serverless developers wanting durable functions beyond timeout limits
  • Anyone building workflows that must complete reliably

Start Building Reliable Systems

Restate makes distributed code reliable by default. Write normal functions, get durable execution.

Need help with distributed systems? I build custom backend solutions — reach out to discuss your project.


Found this useful? I publish daily deep-dives into developer tools and APIs. Follow for more.

Top comments (0)