moxzi
Docs / Actor platforms / Restate

Restatealpha

Run Motoko actors as Restate virtual objects, with state in Restate and delayed calls as timers.

Each actor key is a Restate virtual object. Restate delivers its messages one at a time and keeps its state; timers are Restate delayed calls.

You also need the moxzi SDK and hosts bundles; see Actor platforms.

Prerequisites#

Create and run a project#

moxzi host new restate hello
cd hello
ONCE=1 ./run.sh
actor.mo -> actor.wasm + actor.did (245563 bytes, 1 file(s), 50 steps, 0.66s)
Counter/1.inc() -> [1]

Run it a second time. The host is a new process, and the actor's state comes back from the platform's store:

ONCE=1 ./run.sh
actor.mo -> actor.wasm + actor.did (245563 bytes, 1 file(s), 50 steps, 0.62s)
Counter/1.inc() -> [2]

ONCE=1 exits after the demo. Without it, the host keeps running on port 8090 (set PORT to change it), and you can call any key:

curl -X POST localhost:8090/actors/Counter/2/method/inc \
  -H 'content-type: application/json' -d '[]'

--example ledger and --example saga work on Restate too; see Examples.

The project#

PathContents
actor.moThe Counter actor type. Each key Counter/ID is a separate actor
host/moxzi's Restate adapter. It's yours to change
run.shBuilds the actor and the host, starts what Restate needs, and runs the demo

Change actor.mo and run ./run.sh again. New keys use the new code. Existing keys keep their code until they're upgraded; host/README.md describes upgrades.

How it maps#

Handled by
One message at a time per keyThe Restate virtual object
Actor stateRestate state, in the Restate server container moxzi-hello-restate (ports 18080 and 19080; set RESTATE_PORT to move them)
Durable timersRestate delayed calls

State lives in the Restate server container, not the project directory. Remove it with docker rm -f moxzi-hello-restate to start over.

The project also contains platform-runtimes.env, which pins Restate by version and architecture-specific OCI digest. run.sh verifies the image ID and server-reported version and records them in .restate/runtime-provenance.log. If a same-named container was created from different bytes, startup stops before that container runs. Back up or export its state and follow the Restate migration procedure before replacing it. MOXZI_RESTATE_IMAGE_OVERRIDE accepts only an immutable digest and marks the run outside Moxzi's tested compatibility pair.

Configuration#

VariableDefaultEffect
PORT8090The host's HTTP port
MOXZI_HOST_TOKENrandomToken for the host's control endpoints (/_moxzi/*)
MOXZI_RESTATE_SDK_ADDR127.0.0.1:<PORT+300>Exact Restate SDK listen address; use only an address Restate can reach
MOXZI_RESTATE_SDK_HOST127.0.0.1SDK listen host when MOXZI_RESTATE_SDK_ADDR is unset; the generated Docker run sets 0.0.0.0
MOXZI_RESTATE_REACHlocal SDK URL, or host.docker.internal:<PORT+300> for a remote bindURL registered with Restate
MOXZI_RESTATE_IDENTITY_KEYgenerated for the local serverRestate publickeyv1_... key used to verify every raw SDK request; mandatory off loopback
MOXZI_RESTATE_PREVIOUS_IDENTITY_KEYunsetPrevious public key accepted during a controlled rotation

The matching private PEM is configured on the Restate server through RESTATE_REQUEST_IDENTITY_PRIVATE_KEY_PEM_FILE. The generated project keeps it in the gitignored .restate/ directory. For an external Restate deployment, create and protect your own ED25519 PKCS#8 key, configure its private half on Restate, and give only the encoded public half to the host. Remote SDK binding also requires a nonempty MOXZI_HOST_TOKEN; startup fails if either boundary is missing.

For a rolling key change, first deploy hosts with the new public key as MOXZI_RESTATE_IDENTITY_KEY and the old one as MOXZI_RESTATE_PREVIOUS_IDENTITY_KEY. Then switch Restate to the new private key and remove the previous key after old invocations have drained.

On this pagePrerequisitesCreate and run a projectThe projectHow it mapsConfiguration