Actor state provides the best of both worlds: it’s stored in-memory and persisted automatically. This lets you work with the data without added latency while still being able to survive crashes & upgrades.
Using External SQL Databases
Actors can also be used with external SQL databases. This can be useful to integrate actors with existing applications or for storing relational data. Read more here.
There are two ways to define a actor’s initial state:
The createState
function is called once when the actor is first created. See Lifecycle for more details.
To update state, modify the state
property on the context object (c.state
) in your actions:
Only state stored in the state
object will be persisted. Any other variables or properties outside of this are not persisted.
Actors automatically handle persisting state transparently. This happens at the end of every action if the state has changed.
In the rare occasion you need to force a state change mid-action, you can use c.saveState()
. This should only be used if your action makes an important state change that needs to be persisted before the action completes.
Each actor’s state is completely isolated, meaning it cannot be accessed directly by other actors or clients. This allows actors to maintain a high level of security and data integrity, ensuring that state changes are controlled and predictable.
To interact with a actor’s state, you must use Actions. Actions provide a controlled way to read from and write to the state.
If you need a shared state between multiple actors, you have two options:
In addition to persisted state, RivetKit provides a way to store ephemeral data that is not saved to permanent storage using vars
. This is useful for temporary data that only needs to exist while the actor is running or data that cannot be serialized.
vars
is designed to complement state
, not replace it. Most actors should use both: state
for critical business data and vars
for ephemeral or non-serializable data.
There are two ways to define a actor’s initial vars:
When using static vars
, all values must be compatible with structuredClone()
. If you need to use non-serializable objects, use createVars
instead, which allows you to create these objects on the fly.
Vars can be accessed and modified through the context object with c.vars
:
vars
vs state
In practice, most actors will use both: state
for critical business data and vars
for ephemeral, non-serializable, or performance-sensitive data.
Use vars
when:
Use state
when:
State is constrained to the available memory.
Only JSON-serializable types can be stored in state. In serverless runtimes that support it (Rivet, Cloudflare Workers), state is persisted under the hood in a compact, binary format. This is because JavaScript classes cannot be serialized & deserialized.