Skip to main content
Restate lets you persist key-value (K/V) state using its embedded K/V store.

Key characteristics

State is only available for Virtual Objects and Workflows. Scope & retention:
  • For Virtual Objects: State is scoped per object key and retained indefinitely. It is persisted and shared across all invocations for that object until explicitly cleared.
  • For Workflows: State is scoped per workflow execution (workflow ID) and retained only for the duration of the workflow’s configured retention time.
Access Rules: You can inspect and edit the K/V state via the UI and the CLI.

List all state keys

To retrieve all keys for which the current Virtual Object has stored state:
state_keys = ctx.state_keys()

Get state value

To read a value by key:
my_string = await ctx.get("my-string-key", type_hint=str) or "default-key"
my_number = await ctx.get("my-number-key", type_hint=int) or 123
The return value is None if no value was stored. See the serialization docs to customize the state serializer.

Set state value

To write or update a value:
ctx.set("my-key", "my-new-value")

Clear state key

To delete a specific key:
ctx.clear("my-key")

Clear all state keys

To remove all stored state for the current Virtual Object:
ctx.clear_all()

Advanced: Eager vs. lazy state loading

Restate supports two modes for loading state in handlers:

Eager state (default)

  • How it works: State is automatically sent with the request when invoking a handler
  • Benefits: State is available immediately when the handler starts executing
  • Behavior: All reads and writes to state are local to the handler execution
  • Best for: Small to medium state objects that are frequently accessed

Lazy state

  • How it works: State is fetched on-demand on get calls from the Restate Server
  • Benefits: Reduces initial request size and memory usage
  • Setup: Enable lazy state in the service or handler configuration
  • Best for: Large state objects that aren’t needed in every handler execution
I