This guide takes you through your first steps with Restate. We will run a simple Restate Greeter service that listens on port 9080 and responds with You said hi to <name>! to a greet request. Quickstart Select your SDK:
Select your favorite runtime:
Prerequisites:
1

Install Restate Server & CLI

Restate is a single self-contained binary. No external dependencies needed.
brew install restatedev/tap/restate-server restatedev/tap/restate
Start the server:
restate-server
Find the CLI at:
restate --help
You can find the Restate UI running on port 9070 (http://localhost:9070) after starting the Restate Server.
2

Get the Greeter service template

restate example typescript-hello-world &&
cd typescript-hello-world &&
npm install
View on GitHub
3

Run the Greeter service

npm run app-dev
4

Register the service

Tell Restate where the service is running, so Restate can discover and register the services and handlers behind this endpoint. You can do this via the UI (http://localhost:9070) or via:
restate deployments register http://localhost:9080
Expected output:
 SERVICES THAT WILL BE ADDED:
- Greeter
Type: Service
HANDLER  INPUT                                     OUTPUT
greet    value of content-type 'application/json'  value of content-type 'application/json'


 Are you sure you want to apply those changes? · yes
 DEPLOYMENT:
SERVICE  REV
Greeter  1
If you run Restate with Docker, use http://host.docker.internal:9080 instead of http://localhost:9080.
When using Restate Cloud, your service must be accessible over the public internet so Restate can invoke it. If you want to develop with a local service, you can expose it using our tunnel feature.
5

Send a request to the Greeter service

Invoke the service via the Restate UI playground: go to http://localhost:9070, click on your service and then on playground.Restate UI PlaygroundOr invoke via curl:
curl localhost:8080/Greeter/greet --json '{"name": "Sarah"}'
Expected output:
You said hi to Sarah!
6

Congratulations, you just ran Durable Execution!

The invocation you just sent used Durable Execution to make sure the request ran till completion. For each request, it sent a notification, slept for a second, and then sent a reminder.
const greeter = restate.service({
  name: "Greeter",
  handlers: {
    greet: restate.handlers.handler(
      { input: serde.zod(Greeting), output: serde.zod(GreetingResponse) },
      async (ctx: restate.Context, { name }) => {
        // Durably execute a set of steps; resilient against failures
        const greetingId = ctx.rand.uuidv4();
        await ctx.run("Notification", () => sendNotification(greetingId, name));
        await ctx.sleep({ seconds: 1 });
        await ctx.run("Reminder", () => sendReminder(greetingId, name));

        // Respond to caller
        return { result: `You said hi to ${name}!` };
      },
    ),
  },
});

restate.serve({
  services: [greeter],
  port: 9080,
});
Send a request for Alice to see how the service behaves when it occasionally fails to send the reminder and notification:
curl localhost:8080/Greeter/greet --json '{"name": "Alice"}'
Expected output:
You said hi to Alice!
You can see in the service logs and in the Restate UI how the request gets retried. On a retry, it skipped the steps that already succeeded.Restate UI Durable ExecutionEven the sleep is durable and tracked by Restate. If you kill/restart the service halfway through, the sleep will only last for what remained.
Restate persists the progress of the handler. Letting you write code that is resilient to failures out of the box. Have a look at the Durable Execution page to learn more.