A Turborepo monorepo containing three Express server applications with Restate durable execution: service, object, and workflow.
durable-execution/
├── apps/
│ ├── service/ # Express server (port 3001) + Restate service (port 9080)
│ ├── object/ # Express server (port 3002) + Restate object (port 9081)
│ └── workflow/ # Express server (port 3003) + Restate workflow (port 9082)
├── docker-compose.yml
├── package.json
└── turbo.json
Restate is a durable execution platform that provides:
- Durable execution: Functions survive failures and restarts
- State management: Built-in persistent state per service/object
- Workflows: Long-running, durable workflows with guaranteed completion
- Virtual Objects: Stateful entities with consistent key-based routing
Each app implements a different Restate pattern:
- Service (
service): Stateless Restate service with handlers for greet and process operations - Object (
object): Virtual object with durable state management (setState, getState, clearState) - Workflow (
workflow): Durable workflow with multi-step execution and status tracking
- Node.js >= 18.0.0
- npm >= 10.0.0
- Docker and Docker Compose (for Restate server)
-
Install dependencies for all apps:
npm install
-
Start the Restate server:
npm run restate:up
This starts the Restate server with:
- Ingress port:
8080(for invoking services) - Admin API port:
9070(for deployments and management) - Metrics port:
9071(for monitoring)
- Ingress port:
-
Start all apps in development mode:
npm run dev
This will start:
- service on http://localhost:3001 (Restate endpoint: 9080)
- object on http://localhost:3002 (Restate endpoint: 9081)
- workflow on http://localhost:3003 (Restate endpoint: 9082)
Each app will automatically register its deployment with the Restate server.
# Start Restate server
npm run restate:up
# Stop Restate server
npm run restate:down
# View Restate logs
npm run restate:logsInvoke the greet handler:
curl -X POST http://localhost:8080/service/greet \
-H "Content-Type: application/json" \
-d '"World"'Invoke the process handler:
curl -X POST http://localhost:8080/service/process \
-H "Content-Type: application/json" \
-d '{"data": "test"}'Set state for an object (key: "my-object"):
curl -X POST http://localhost:8080/object/my-object/setState \
-H "Content-Type: application/json" \
-d '{"value": "hello", "count": 42}'Get state:
curl -X POST http://localhost:8080/object/my-object/getState \
-H "Content-Type: application/json" \
-d 'null'Clear state:
curl -X POST http://localhost:8080/object/my-object/clearState \
-H "Content-Type: application/json" \
-d 'null'Start a workflow (key: "workflow-1"):
curl -X POST http://localhost:8080/workflow/workflow-1/run/send \
-H "Content-Type: application/json" \
-d '{"task": "process-order", "orderId": "12345"}'Get workflow status:
curl -X POST http://localhost:8080/workflow/workflow-1/getStatus \
-H "Content-Type: application/json" \
-d 'null'Each app has monitoring endpoints:
# Service
curl http://localhost:3001/
curl http://localhost:3001/health
# Object
curl http://localhost:3002/
curl http://localhost:3002/health
# Workflow
curl http://localhost:3003/
curl http://localhost:3003/healthList all deployments:
curl http://localhost:9070/deploymentsList all services:
curl http://localhost:9070/servicesView Restate metrics:
curl http://localhost:9071/metrics-
Start Restate server first:
npm run restate:up
-
Start apps in dev mode (with hot reload):
npm run dev
-
Make changes - Apps will automatically reload and re-register with Restate
-
View logs:
npm run restate:logs # Restate server logs # App logs appear in the terminal where you ran npm run dev
npm run build# Ensure Restate is running
npm run restate:up
# Start all apps
npm run start- Functions survive process restarts and failures
- Automatic retries with exponential backoff
- Guaranteed exactly-once execution
- Persistent state per object key
- Strongly consistent reads/writes
- State survives failures
- Long-running workflows with multiple steps
- Durable sleep and timers
- Progress tracking and status queries
- Each app registers its deployment on startup
- No manual deployment configuration needed
- Automatic re-registration on code changes
Make sure Restate server is running:
npm run restate:up
docker ps | grep restatePorts used:
- 3001-3003: Express servers
- 9080-9082: Restate endpoints
- 8080, 9070, 9071: Restate server
Change ports via environment variables:
PORT=4001 npm run dev # For Express
# Edit Restate endpoint ports in src/index.ts# Restate logs
npm run restate:logs
# Docker logs
docker logs restate-server
# Individual app
cd apps/service && npm run dev# Stop and remove Restate container
npm run restate:down
# Clean build artifacts
npm run clean- Turborepo - Monorepo build system
- TypeScript - Type-safe JavaScript
- Express - Web framework for monitoring endpoints
- Restate SDK - Durable execution framework
- tsx - TypeScript execution for development
- Docker - Container runtime for Restate server