For durable execution to work correctly, Restate must know exactly which version of your code to use for each request. This requires understanding three key concepts: deployments, registration, and versioning.

What is a Deployment?

A deployment in Restate is a specific, versioned instance of your service code—whether running as an HTTP endpoint, a Lambda function, or another supported environment. Each deployment is immutable: once registered, its code and endpoint must not change. An invocation is bound to a specific deployment — it starts and completes within that same deployment. This ensures that in-flight requests always see the code they started with, preserving correctness and determinism.

Registering a Deployment

After deploying your service, you must register it with Restate so it can be discovered and invoked. You can register a deployment using:
  • The Restate UI (recommended for most users)
  • The CLI:
    restate deployments register http://localhost:9080
    
  • The Admin API:
    curl localhost:9070/deployments --json '{"uri": "http://localhost:9080"}'
    
Note:
  • For AWS Lambda, use the function ARN instead of a URL (e.g., arn:aws:lambda:region:account-id:function:function-name:version).
  • If running Restate in Docker, use host.docker.internal instead of localhost.

Deployments supporting only HTTP1.1

Some deployments only support HTTP/1.1, and not HTTP/2. This means Restate cannot use bidirectional streaming of journal entries and needs to communicate with the service in request-response mode (learn more). To register such deployments, you need to specify using HTTP/1.1 during registration:
restate deployments register http://localhost:9080 --use-http1.1
When registering deployments via the UI, you can select the HTTP/1.1 checkbox.

Deploying new service versions

Since deployments are immutable, updates require creating new deployments:
1

Deploy new version

Deploy your updated service code to a new endpoint (e.g., http://greeter-v2/).
2

Register the new deployment

Then register it with Restate:
restate deployments register http://greeter-v2/
Restate automatically routes new requests to the latest deployment. Existing requests continue on the original deployment.
3

Wait for old deployment to drain

Ensure the old deployment remains available until all in-flight invocations complete.Check for in-flight invocations on this deployment via the UI or CLI.
CLI
# Find the deployment ID of your service
restate services list
# Then, check the number of active invocations for the deployment
restate deployments list
# Or check the deployment details
restate deployment describe <deployment_id>
4

Remove old deployment

Once all invocations are complete, you can safely remove the old deployment. Use the CLI or UI to remove it.
restate deployments remove dp_14LsPzGz9HBxXIeBoH5wYUh
If the deployment isn’t drained yet, but you still want to remove it, use the --force flag in CLI, or ?force=true for curl.
Virtual Object state persists across versions. Ensure your state schema remains backward compatible.

Removing a service

Restate does not support removing individual services directly. Instead, you must remove the deployment that contains the service. To do this safely, follow the steps below:
  1. Ensure no other handlers or services have business logic that calls the service you’re removing.
  2. If several services are bundled in the same deployment, you can’t remove only one of them. You have to remove the whole deployment. So make sure that you first deploy the services you want to keep in a separate new deployment.
  3. Make the service private to avoid accepting new HTTP requests.
  4. Check whether the service has pending invocations by filtering the invocations on deployment ID in the UI or via restate services status, and wait until the service is drained (i.e. no ongoing invocations).
When all prerequisites are fulfilled, you can remove the deployment containing the service via the UI or via:
restate deployments remove dp_14LsPzGz9HBxXIeBoH5wYUh
If the deployment isn’t drained yet but you still want to remove it, use the --force flag in CLI, or ?force=true for curl.

Advanced: Updating deployments in-place

While deployments should be immutable, critical bugs sometimes require updating deployed code to fix stuck invocations.

When This is Needed

If a bug (like a null pointer exception) occurs mid-execution, registering a new deployment only fixes new invocations. Existing stuck invocations need the original deployment fixed.

Two Approaches

  1. Update underlying code at the same URI (works for K8s, not Lambda)
  2. Update deployment endpoint to point to a patched version:
    curl -X PUT localhost:9070/deployments/dp_14LsPzGz9HBxXIeBoH5wYUh \
      --json '{"uri": "http://greeter-patched/"}'
    

Common Scenarios

See also