Restate Go SDK 1.0
We're pleased to announce the release of Restate Go SDK 1.0 π
Migration guide
If you're upgrading from 0.x, follow this migration guide, or point your coding agent at it: MIGRATION.md.
Changes to the SDK modules
The SDK is now split into several independently versioned Go modules. In particular:
- SDK remains
github.com/restatedev/sdk-go - Testing now needs to be pulled separately using
go get github.com/restatedev/sdk-go/testing@v1.0.0, to avoid dependency pollution
We're committing to 1.x semver guarantees for SDK and testing module and submodules, except internal and x submodules.
We keep as experimental modules:
- Mocks:
go get github.com/restatedev/sdk-go/x/mocks@v0.26.0 - Protoc plugin:
go get github.com/restatedev/sdk-go/x/protoc-gen-go-restate@v0.26.0
Revamped error interfaces
We've overhauled the error interfaces used in the SDK APIs to be more explicit and to make them easier to use and evolve:
TerminalErrorcompletes the invocation (or aRun) with a failure, with optional status code and metadata. You can build terminal errors usingrestate.ToTerminalErrororrestate.TerminalErrorf.RetryableErroris a non-terminal failure that gets retried (a status code). We will evolve this type in the future to support customizing the retry behavior.
BREAKING: Because
TerminalErroris now a type, the oldTerminalError(...)constructor was
renamed toToTerminalError:
Context operations such as Get, Run, Call and Wait now return a TerminalError directly instead of a generic error.
This makes the SDK's error-handling model explicit right in the signatures: return a TerminalError for failures that are recorded in the Restate journal, and panic on any other error to let Restate retry.
Randomness uses math/rand/v2
Rand(ctx) now returns a standard-library *math/rand/v2.Rand instead of a custom
interface, so the full stdlib API is available. It's still seeded deterministically (same
sequence on every replay) and must not be used inside Run. UUIDs moved to their own
helper:
id := restate.Rand(ctx).UUID().String() // 0.x
id := restate.UUID(ctx).String() // 1.0
// the whole math/rand/v2 surface now works (deterministic, replay-safe):
r := restate.Rand(ctx)
roll := r.IntN(6) + 1Solidified options
We've cleaned up the option vocabulary across the SDK so it's consistent and easier to evolve:
- Retry policy options are now a single shared vocabulary: the same builders work for
Run/RunAsync/RunVoidand for the invocation retry policy (WithInvocationRetryPolicy), with consistent names and types. - Codecs are simplified: a single
encoding.Codecis used everywhere (handlers, services, ingress, value operations), set withWithCodec, and input/output codecs can now be configured independently viaWithInputCodec/WithOutputCodec.
See MIGRATION.md for the exact renames.
(Preview) Scope and limit key to enable flow control
This release adds the SDK API for flow control, the new Restate 1.7 feature to cap how many invocations run concurrently within a scope, with optional hierarchical limit keys. Use it to bound cost (especially for AI agents, where every concurrent invocation is real model/API spend), shield downstream systems from bursts, and share capacity fairly across tenants.
To use scope and limit keys in service to service communication:
// Route every call made through this client into a named scope.
out, err := restate.Service[Output](ctx, "MyService", "Process",
restate.WithScope("tenant-123")).
Request(input)
// Add a hierarchical limit key for finer-grained concurrency limits.
out, err := restate.Service[Output](ctx, "MyService", "Process",
restate.WithScope("tenant-123")).
Request(input, restate.WithLimitKey("api-key/user42"))WithScope works on Service, Object and Workflow clients (and their β¦Send
variants); WithLimitKey works on both in-context calls and ingress requests/sends.
NOTE: This API is in preview and is not enabled by default. To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features via
RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=trueandRESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true(new clusters only). See https://docs.restate.dev/services/flow-control for details.
New Signals API
Signals are a first-class way for one invocation to communicate with another: an
invocation waits on a named signal, and any other handler resolves or rejects it by
referencing the target invocation's ID.
// Inside the waiting invocation β block until the signal arrives:
approved, err := restate.Signal[bool](ctx, "approved").Result()
// A SignalFuture can also be combined with others via Context.Select,
// exactly like awakeables, calls and timers.// Inside another handler β resolve or reject by target invocation ID:
restate.ResolveSignal(ctx, targetInvocationID, "approved", true)
restate.RejectSignal(ctx, targetInvocationID, "approved", restate.TerminalErrorf("denied"))Noteworthy bumps
- Minimum Go version: 1.24 β 1.25.
testcontainers-goremoved from the core module. It now lives only in thetesting
module (bumped tov0.43.0there), so consumers of the SDK no longer inherit Docker and
its dependency tree.go.opentelemetry.io/otelv1.38.0 β v1.44.0google.golang.org/protobufv1.36.10 β v1.36.11github.com/invopop/jsonschemav0.13.0 β v0.14.0
What's Changed
- Update shared core by @slinkydeveloper in #137
- Bump sdk test suite by @slinkydeveloper in #138
- Update shared core by @slinkydeveloper in #140
- Refactor connection handling in ExecuteInvocation and IO helpers #132 by @neerajvipparla in #143
- Update shared core, remove take output EOF case by @slinkydeveloper in #145
- Move stream draining to request handler by @muhamadazmy in #146
- Add/go license #134 by @neerajvipparla in #144
- Fix license check CI step: match Go version to go.mod by @slinkydeveloper in #147
- Scopes and signals by @slinkydeveloper in #148
- Pre 1.0 changes by @slinkydeveloper in #149
- Dep bumps by @slinkydeveloper in #150
- Bump jsonschema dependency by @slinkydeveloper in #151
- Bump testcontainers dependency by @slinkydeveloper in #152
- Fix API change with testcontainers by @slinkydeveloper in #153
- Remove exclusions we dont need by @slinkydeveloper in #154
New Contributors
- @neerajvipparla made their first contribution in #143
Full Changelog: v0.24.0...v1.0.0