Crash Course
Actors for long-lived processes with durable state, realtime, and hibernate when not in use.
Features
- Long-Lived, Stateful Compute: Each unit of compute is like a tiny server that remembers things between requests – no need to re-fetch data from a database or worry about timeouts. Like AWS Lambda, but with memory and no timeouts.
- Blazing-Fast Reads & Writes: State is stored on the same machine as your compute, so reads and writes are ultra-fast. No database round trips, no latency spikes. State is persisted to Rivet for long term storage, so it survives server restarts.
- Realtime: Update state and broadcast changes in realtime with WebSockets. No external pub/sub systems, no polling – just built-in low-latency events.
- Infinitely Scalable: Automatically scale from zero to millions of concurrent actors. Pay only for what you use with instant scaling and no cold starts.
- Fault Tolerant: Built-in error handling and recovery. Actors automatically restart on failure while preserving state integrity and continuing operations.
When to Use Rivet Actors
- AI agents & sandboxes: multi-step toolchains, conversation memory, sandbox orchestration.
- Multiplayer or collaborative apps: CRDT docs, shared cursors, realtime dashboards, chat.
- Workflow automation: background jobs, cron, rate limiters, durable queues, backpressure control.
- Data-intensive backends: geo-distributed or per-tenant databases, in-memory caches, sharded SQL.
- Networking workloads: WebSocket servers, custom protocols, local-first sync, edge fanout.
Common Patterns
Actors scale naturally through isolated state and message-passing. Structure your applications with these patterns:
Actor Per Entity
Create one actor per user, document, or room. Use compound keys to scope entities:
Coordinator & Data Actors
Data actors handle core logic (chat rooms, game sessions, user data). Coordinator actors track and manage collections of data actors—think of them as an index.
Sharding
Split high-load actors by time, user ID, or random key:
Fan-In & Fan-Out
Distribute work across workers (fan-out) and aggregate results (fan-in):
Anti-Patterns
”God” actor
Avoid a single actor that handles everything. This creates a bottleneck and defeats the purpose of the actor model. Split into focused actors per entity instead.
Actor-per-request
Actors maintain state across requests. Creating one per request wastes resources and loses the benefits of persistent state. Use actors for persistent entities and regular functions for stateless work.
Minimal Project
Backend
actors.ts
server.ts
Integrate with the user’s existing server if applicable. Otherwise, default to Hono.
Minimal Client
See the client quick reference for more details.
Actor Quick Reference
State
Persistent data that survives restarts, crashes, and deployments. State is persisted on Rivet Cloud or Rivet self-hosted, so it survives restarts if the current process crashes or exits.
Keys
Keys uniquely identify actor instances. Use compound keys (arrays) for hierarchical addressing:
Don’t build keys with string interpolation like "org:${userId}" when userId contains user data. Use arrays instead to prevent key injection attacks.
Input
Pass initialization data when creating actors.
Temporary Variables
Temporary data that doesn’t survive restarts. Use for non-serializable objects (event emitters, connections, etc).
Actions
Actions are the primary way clients and other actors communicate with an actor.
Events & Broadcasts
Events enable real-time communication from actors to connected clients.
Connections
Access the current connection via c.conn or all connected clients via c.conns. Use c.conn.id or c.conn.state to securely identify who is calling an action. Connection state is initialized via connState or createConnState, which receives parameters passed by the client on connect.
Actor-to-Actor Communication
Actors can call other actors using c.client().
Scheduling
Schedule actions to run after a delay or at a specific time. Schedules persist across restarts, upgrades, and crashes.
Destroying Actors
Permanently delete an actor and its state using c.destroy().
Lifecycle Hooks
Actors support hooks for initialization, connections, networking, and state changes.
Helper Types
Use ActionContextOf to extract the context type for writing standalone helper functions:
Errors
Use UserError to throw errors that are safely returned to clients. Pass metadata to include structured data. Other errors are converted to generic “internal error” for security.
Low-Level HTTP & WebSocket Handlers
For custom protocols or integrating libraries that need direct access to HTTP Request/Response or WebSocket connections, use onRequest and onWebSocket.
HTTP Documentation · WebSocket Documentation
Versions & Upgrades
When deploying new code, configure version numbers to control how actors are upgraded:
Or use environment variable: RIVET_RUNNER_VERSION=2
Common version sources:
- Build timestamp:
Date.now() - Git commit count:
git rev-list --count HEAD - CI build number:
github.run_number,GITHUB_RUN_NUMBER, etc.
JavaScript Client Quick Reference
Stateless vs Stateful
Getting Actors
Connection Parameters
Pass parameters when connecting to actors for authentication or configuration:
Subscribing to Events
Connection Lifecycle
Calling from Backend
Call actors from your server-side code.
React Quick Reference
Setup
useActor & Calling Actions
Subscribing to Events
Authentication & Security
Validate credentials in onBeforeConnect or createConnState. Throw an error to reject the connection. Use c.conn.id or c.conn.state to identify users in actions—never trust user IDs passed as action parameters.
CORS (Cross-Origin Resource Sharing)
Validate origins in onBeforeConnect to control which domains can access your actors: