Restate 1.1.0 and multiple SDKs released
Posted September 11, 2024 by Restate Team ‐ 6 min read
Release Announcement: Restate 1.1.0 and SDK updates
We are pleased to announce that Restate 1.1.0 is available – an important milestone which includes a multitude of under-the-covers fixes, forward-compatibility with upcoming features, and improved performance. You can see the full changelog on GitHub. Together with the new release, we are also sharing updates about three new SDKs for building durable services with Restate.
First, a word about compatibility. As operators of Restate ourselves, we want to make sure that Restate cluster deployments can be easily upgraded to the latest release. To that end we are making it easy by ensuring that you will always be able to go up to the next minor version, handling any necessary migrations internally. And to give you additional confidence to move up to the latest release, we also support downgrading to the immediate prior minor version. The latter promise requires that no optional new features have been activated since the upgrade. For more information on Restate server management, please see our guidance on upgrades and data backup.
Performance improvements
Restate 1.1.0 contains important changes that pave the way for upcoming features and add necessary infrastructure on the path towards distributed deployments. Thanks to some internal cleanups in the Restate durable log component, the new version also brings improved latency and throughput. In a test involving a single-step workflow running on an EC2 c6id.8xlarge
instance with fast local SSD storage, we measured improved throughput by 9.6% (15,900 RPS up to 17,450 RPS) while reducing 99th percentile response time latency by 58% (from 90 ms down to 38 ms at p99) relative to Restate version 1.0.2. On a lower end m6g.2xlarge
instance with EBS gp3
storage, the improvements are even more pronounced. We measured a throughput increase of 37% (2,992 RPS to 4,118 RPS) and a five-fold drop in 99th percentile response time (756ms to 140ms).
Restate version | Compute type | Storage type | Throughput (rps) | p50 (ms) | p75 (ms) | p90 (ms) | p99 (ms) | Max (ms) |
---|---|---|---|---|---|---|---|---|
1.1.0 | c6id.8xlarge | Local NVMe | 17,453.31 | 22.42 | 24.92 | 28.18 | 37.51 | 69.01 |
1.0.2 | c6id.8xlarge | Local NVMe | 15,912.89 | 22.35 | 35.84 | 52.34 | 90.73 | 200.50 |
1.1.0 | c6id.8xlarge | EBS io2 | 10,409.14 | 37.71 | 41.92 | 47.24 | 60.09 | 102.82 |
1.0.2 | c6id.8xlarge | EBS io2 | 9,994.65 | 38.25 | 47.94 | 58.63 | 81.83 | 181.75 |
1.1.0 | m6g.2xlarge | EBS gp3 | 4,118.83 | 39.71 | 50.29 | 83.75 | 140.25 | 246.70 |
1.0.2 | m6g.2xlarge | EBS gp3 | 2,992.92 | 52.83 | 86.67 | 141.25 | 756.10 | 1,990.00 |
Since Restate throughput and response times are highly dependent on the deployed services with which it collaborates, we wanted a consistent way to measure performance of the Restate server itself, and thus the overhead that durable execution with Restate would add to a service or workflow. Our test method deploys a highly optimized Rust-based mock service running on the same host as Restate. This synthetic setup lets us isolate the Restate-specific latencies. To conduct your own end-to-end performance baseline measurements, you can start by replicating our test configuration available on GitHub.
SDKs
Since our latest release blog post, we have substantially increased the SDKs we offer with three new platforms. This brings the total to seven directly-supported languages across five distinct ecosystems! You can now develop Restate services in Go, Python, Java/Kotlin (and any interoperable JVM-based language), JavaScript/TypeScript, and the much-awaited Rust too! Just type restate examples
and get started with one of our templates/examples:
Go SDK
We revealed the Restate Go SDK in the July community call and since then have been steadily iterating on it. To give you a taste of what you can expect, a typical service handler in Go looks like this:
package main
import (
"context"
"fmt"
"log/slog"
"os"
restate "github.com/restatedev/sdk-go"
"github.com/restatedev/sdk-go/server"
)
type Greeter struct{}
func (Greeter) Greet(ctx restate.Context, greeting string) (string, error) {
return fmt.Sprintf("%s!", greeting), nil
}
func main() {
server := server.NewRestate().Bind(restate.Reflect(Greeter{}))
if err := server.Start(context.Background(), ":9080"); err != nil {
slog.Error("application exited unexpectedly", "err", err.Error())
os.Exit(1)
}
}
You can get started by following the official Go template or take a look at https://github.com/restatedev/sdk-go repository and the additional examples it contains, or head over to docs.restate.dev for more.
Python SDK
The Python SDK is one of the latest additions to the list of officially supported languages, and we can’t wait to see what you will build with it!
The following is a snippet to get you a taste of the new SDK
import restate
counter = restate.VirtualObject("counter")
@counter.handler()
async def increment(ctx, value: int) -> int:
n = await ctx.get("counter") or 0
n += value
ctx.set("counter", n)
return n
app = restate.app(services=[counter])
This is an ASGI v3 application, and you can serve it with your favorite asgi compatible HTTP server.
To get started:
pip install restate_sdk
And head over to https://github.com/restatedev/sdk-python or docs.restate.dev to learn more.
Rust SDK
The long awaited Rust SDK is here for you to take for a spin! The following is the obligatory greeter:
use restate_sdk::prelude::*;
#[restate_sdk::service]
trait Greeter {
async fn greet(name: String) -> Result<String, HandlerError>;
}
struct GreeterImpl;
impl Greeter for GreeterImpl {
async fn greet(&self, _: Context<'_>, name: String) -> Result<String, HandlerError> {
Ok(format!("Greetings {name}"))
}
}
#[tokio::main]
async fn main() {
HttpServer::new(Endpoint::builder().bind(GreeterImpl.serve()).build())
.listen_and_serve("0.0.0.0:9080".parse().unwrap())
.await;
}
The SDK provides an out-of-the-box batteries-included experience using Tokio and hyper.rs, battle tested network libraries widely used in high-performance environments.
To get started, just add the restate-sdk
crate as dependency together with tokio
:
[dependencies]
restate-sdk = "0.3"
tokio = "1.0"
Head over to https://github.com/restatedev/sdk-rust to learn more!
Development experience
Run retry policy
It is now possible, on selected SDKs, to provide an upper-bound on the amount of retries/duration of retries for ctx.run
. When the retry limits are exhausted, the SDK will convert the “retryable error” into a “terminal error” recording the failure.
We release this feature as preview feature: the feature is ready to be used, but we would like to get community feedback before we include it in the stable API.
For example, in Kotlin:
@Service
class RunRetryPolicy {
@OptIn(UsePreviewContext::class)
@Handler
suspend fun run(ctx: Context) {
ctx.runBlock(retryPolicy = retryPolicy {
// Stop retrying when either maxDuration or maxAttempts is reached first
maxDuration = 60.seconds
maxAttempts = 20
}) {
throw IllegalStateException("I will never succeed")
}
}
}
fun main() {
RestateHttpEndpointBuilder.builder()
.bind(RunRetryPolicy())
// You need to enable the preview context from the endpoint builder too.
.enablePreviewContext()
.buildAndListen()
}
At the moment this feature is implemented in the Java/Kotlin, Rust, and Python SDKs.
Your feedback matters!
We have shipped a long list of improvements over the last months, driven by community feedback. The Restate server now handles tracing headers and works better with certain types of load balancers, the Java SDK has received several bug fixes, the TypeScript SDK now allows customers to plug in custom serialization formats, the CLI/SQL interface exposes additional information about your service invocation, and many more. We are very grateful for all your input!
You can get the latest Restate and SDKs from the Get Restate page. As always, let us know what you think at @restatedev, or join Discord or Slack to talk with the team and get notified about new features and announcements.