Service deployments
A service deployment is a specific instance of your service code associated with an HTTP endpoint, a Lambda function, or other supported environment. Deployments can be managed through the Restate UI, the CLI, or the Admin REST API:Some deployment targets support only HTTP/1.1. Use
--use-http1.1 when registering these deployments.For AWS Lambda, use the function ARN instead of a URL. See AWS Lambda deployment.
Automatic versioning with FaaS platforms
Function-as-a-Service (FaaS) platforms automatically handle immutable versioning through version-specific URLs or ARNs. This makes them ideal for Restate deployments as they eliminate the complexity of manual version management. Have a look at the dedicated deployment docs to learn more:- Vercel: Register the Commit URL so that Restate can address specific Vercel deployments.
- AWS Lambda: When you publish a Lambda function, it automatically creates an immutable version with a unique ARN that never changes.
- Deno Deploy: Register the Preview URLs so that Restate can target specific Deno deployments.
- Cloudflare Workers: Register the Preview URLs so that Restate can target specific Cloudflare deployments.
Automatic versioning with Kubernetes Operator
The Restate Kubernetes operator provides a higher-level abstraction for managing service deployments and their versions automatically. The operator handles the complete versioning lifecycle:- Deploy new versions: Create a new
RestateDeploymentwith your updated container image - Automatic registration: The operator registers the new deployment with the Restate cluster
- Traffic routing: New requests automatically route to the latest version
- Graceful draining: The operator monitors older deployments for ongoing invocations
- Auto-scaling to zero: Once drained, older versions automatically scale to zero
Manual versioning
For non-FaaS deployments, you can use either the UI or the CLI to manage deployments. The typical update flow looks like this:Register the new deployment
Then register it with Restate:Restate automatically routes new requests to the latest deployment. Existing requests continue on the original deployment.
CLI
Monitor deployment status
Check for in-flight invocations on deployments via the UI or CLI.
Virtual Object state persists across versions. Ensure your state schema remains backward compatible.
Local development
During local development, you’re iterating quickly on your code and don’t need immutable deployments. You can safely re-register the same endpoint after code changes using the--force flag:
In-flight invocations might keep failing with non-determinism errors, but this is typically fine during development.You can kill all the in-flight invocations to a service using either CLI or UI:
CLI
Advanced operations and troubleshooting
This section covers common scenarios you may encounter when managing deployments, and some of the troubleshooting best practices we recommend.Journal mismatch errors
Restate performs journal compatibility checks during replay to prevent corruption. When you see a journal mismatch error (RT0016), it means the code executed during replay has produced a different journal than the original execution. This is typically caused by two scenarios: Non-deterministic code: Code that produces different results on each execution, even with the same inputs. Examples of non-deterministic operations:- External operations such as HTTP requests
- Random value generation:
Math.random(),uuid.v4(), etc. - Getting the current time or date:
new Date() - Iterating over unordered collections, such as hash maps
ctx.run.
For more info, see the durable steps documentation: TypeScript, Python, Java/Kotlin, Go.
In-place code changes: Modifying deployed code at the same endpoint. This violates the immutable deployment principle and can cause in-flight invocations to fail when they replay with the updated code.
Unsafe changes include:
- Reordering Restate SDK operations (
run, state access, service calls, awakeables) - Adding or removing SDK operations in the execution path
- Changing operation inputs (state keys, service call payloads)
- Modifying conditional logic that affects which operations execute
Fixing a bug by updating deployed code
If you have a bug in your deployment code, sometimes it is safe to fix it by updating the deployment in-place.| Change | Safe? |
|---|---|
Fixing a bug inside ctx.run | ✅ |
| Fixing a bug that consistently reproduces (e.g. deserialization error) | ✅ |
| Changing the order of Restate operations, or adding/removing them | ❌ |
| Changing operation inputs (state keys, call payloads, etc.) | ❌ |
This approach doesn’t work on FaaS platforms (e.g. Lambda) or with the Kubernetes Operator, since these use immutable deployments by design.
In those cases, use pause and resume instead.
Pause invocations and resume on a new deployment
This is the recommended approach for fixing bugs affecting in-flight invocations. It works on all platforms, including FaaS and Kubernetes. When a bug affects in-flight invocations, they remain pinned to the original deployment. Registering a new deployment with a fix only helps new invocations. To fix existing invocations:
The fix must be compatible with already-executed journal entries so they can replay successfully.
If the business logic differs, the invocation will fail with non-determinism errors.
For more details, see managing invocations.
Reassigning a deployment endpoint
You can use the Admin API to change which endpoint a deployment points to. This is useful when you’ve deployed a fix to a new URL and want stuck invocations to use it:Updating a service interface
When you register a new deployment, Restate validates that it doesn’t break existing service interfaces: adding handlers is allowed, but removing or renaming them is not. For example, given you register a new deployment for the already existing serviceGreeter, renaming its handler from greet to sayGreet is a breaking change, thus registration will fail.
To allow breaking changes, use the --breaking flag:
Removing a service
In Restate to remove a service, you must remove the deployment that contains it. To do this safely, follow the steps below:- Ensure no other handlers or services have business logic that calls the service you’re removing.
- 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.
- Make the service private to avoid accepting new HTTP requests.
- 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).
--force flag in CLI.