Add AgentOS daemon control plane and maintenance tooling

This commit is contained in:
-Puter
2026-07-19 06:29:51 +05:30
parent a37e0cc3c9
commit ec84c52155
621 changed files with 97578 additions and 15 deletions

View File

@@ -0,0 +1,19 @@
# Actor Configuration
> Source: `src/content/docs/general/actor-configuration.mdx`
> Canonical URL: https://rivet.dev/docs/general/actor-configuration
> Description: This page documents the configuration options available when defining a RivetKit actor. The actor configuration is passed to the `actor()` function.
---
## Basic Example
## Configuration Reference
## Related
- [Registry Configuration](/docs/general/registry-configuration): Configure the RivetKit registry
- [State](/docs/actors/state): Managing actor state
- [Actions](/docs/actors/actions): Defining actor actions
- [Lifecycle](/docs/actors/lifecycle): Actor lifecycle hooks
_Source doc path: /docs/general/actor-configuration_

View File

@@ -0,0 +1,452 @@
# Architecture
> Source: `src/content/docs/general/architecture.mdx`
> Canonical URL: https://rivet.dev/docs/general/architecture
> Description: - rivetkit is the typescript library used for both local development & to connect your application to rivet - a rivetkit instance is called a "runner." you can run multiple runners to scale rivetkit horizontally. read omre about runners below.
---
## 3 ways of running
### rivetkit
- rivetkit is the typescript library used for both local development & to connect your application to rivet
- a rivetkit instance is called a "runner." you can run multiple runners to scale rivetkit horizontally. read more about runners below.
#### local development
- in local development, rivetkit provides a full actor environment for single-node deployments
#### drivers
- rivetkit supports multiple drivers. currently supports: file system (default in local dev), memory, rivet engine (used for rivet cloud & self-hosting), cloudflare durable objects (does not rely on rivet engine)
- drivers are very flexible to enable you to write your actors once and plug in to any system that fits your architecture adequately
- see the driver interface
- actordriver https://github.com/rivet-dev/rivet/blob/eeb01fc4d9ca0e06f2e740d267bd53280ca7330e/rivetkit-typescript/packages/rivetkit/src/actor/driver.ts
- managerdriver https://github.com/rivet-dev/rivet/blob/eeb01fc4d9ca0e06f2e740d267bd53280ca7330e/rivetkit-typescript/packages/rivetkit/src/manager/driver.ts
### rivet cloud
- provides multi-region and highest performance out of the box
- accessible at dashboard.rivet.dev and the api is avialble at api.rivet.dev
### rivet self-hosted
- available as a standalone rust binary or a docker contianer
- can be configured to persist to postgres or rocksdb
- can scale horiziontally across multipe nodes and can scale across multiple regions
- see [self-hosting docs](/docs/self-hosting/)
## actors
- Actors for long-lived processes with durable state, realtime, and hibernate when not in use. read more about actors at a high level at (link to actors/index)
### actor-per-entity
- actors are designed to have an actor-per-entity
- you can think about actors a bit like objects in object-oriented programming where each is responsible for their own state and expose methods (ie actions in our case)
- examples include
- actor per user
- actor per user session
- actor per document
- actor per game room
- actor per tenant
- actor per rate limit topic
### architecting for scale
- actors scale by:
- having isolated state to each actor that combines compute and storage for in-memory reads and writes
- communication is standardized based on actions & events
- scale horizontally
- read more about scaling at [Design Patterns](/docs/actors/design-patterns)
### horizontal scaling
- actors can run across multiple rivetkit runners. this is orchestrated by rivetkit itself.
### lifecycle
actors have create, destroy, wake, and sleep lifecycle hooks that you can implement to modify behavior. see the lifecycle docs for reference on actor lifecycel hook sequences
### actor sleeping
- actors sleep when not in use
- an actor is considered not in use when there are no active network connections to the actor (or the network connections are hibernatable websockets, see below) and there are no actions in flight
- actors have a sleep timeout (configured in `options.sleepTimeout`) that decides how long to keep the actor in memory with no recent activity
- sleep can be held off for the lifetime of a promise with `c.keepAwake(promise)`
- see the [sleeping docs](/docs/actors/lifecycle#sleeping) for full details
### wake events
- actors can wake to any of the follwoing events:
- network requests
- websocket messages
- alarms (see scheduling docs)
### live actor migration
- live actor migrations lets your application ugprade, crash, or hot reload cahnges without interruption to your user or application (including websockets)
- this is powered by hibernating websockets for live websocket migraiton & our fault tolerance mechanism (read more below)
### coldstart performance
- actors have negligible coldstart performance. the code to run the actor is already started (ie the runner), so creating/starting an actor is incredibly cheap.
- creating new actors with a key requires some overhead to communicate with other regions in order to reserve the actor's key (see below). actors can be created without keys with near-0 latency.
### multi-region, globally unique actor keys
- actors can optionally have a globally unique "key"
- when creating an actor with a key
- this system is highly optimized to reduce wan round trips using per-key Paxos with a custom database called Epoxy (https://github.com/rivet-dev/rivet/tree/main/engine/packages/epoxy)
- limitation: when creating an actor with a given key, that key will always be pinned to that region even if the actor is destroyed. creating a new actor with the same key will always live in the same region.
- see the actors keys document
### input
- actors have input data that can be passed to them when constructed
- this is similar to apssing data to a constructor in an object
### generic parameters
actor definitions include the following generic parameters that you'll see frequently in the code:
- state
- conn state
- conn params
- ephemeral variables
- input data
- (experimental) database connector
### persistence
- state automatically flushes to storage intelligently
- to force a state flush and wait for it to finish, call (TODO: look this up in state document)
- read more about state persistence in the state document (link to document)
- state is stored in the same place as where the actor lives. loading an actor in to memory has comparable performance to network attached storage, and once in memory, has performance of any standard in-memory read/write like a variable.
### scheduling & alarms
- actors have a scheduling api to be able to wake up at any time in the indefinite future
- think of this like setTimeout but without a max timeout
- rivet is responsible for waking the actor when this timeout wakes
### ephemeral variables
- actors have the ability to create ephemrla variables for things that you do not want to be persisted with the actor's state
- this is useful for non-serializable data like a utility class like a pubsubs erver or something (TODO extra info)
- link to ephemeral variables docs
### actions
- for stateless clients, actions are sent as http requests via `POST /gateway/{actor id}/actions/{action name}`
- for stateful clients, actions are sent as websocket messages
### events & subscriptions
- events are sent as websocket messages
### error handling
- this is different than fault tolerance:
- error handling is a user error
- fault tolerance is something goes wrong that your applciation was not built to handle (ie hard crash, oom, network error)
- rivet provdies a special UserError class to throw custom errors that will be returned to the client
- all other errors are returned as a generic "internal error"
- this is becuase leaking error deatils is a common security hole, so we default to expose-nothing errors
### logging
- rivet uses pino for logging
- we expose a scoped child logger for each actor at `c.log` that automatically logs the actor id + key
- this allows you to search lgos easily by actor id without having to log the actor id frequently
- logs can be configured via the `RIVET_LOG_LEVEL` env var
### fault tolerance
- actors are fault tolerant, meaning that the host machine can crash and the actors will proceed to operate as if nothing happened
- runners maintain a socket with rivet engine. when this socket closes or takes to long to ping, actors will reschedule
- hibernating websockets (enabled by default) will live-migrate to the new actor as if nothing happened
### crash policy
- there are 3 crash policies: sleep, restart, and destroyed
- sleep (default, usually the option you want):
- when to use: actors that need high-performance in-memory logic.
- when not to use: you need this actor running at all times no matter what, even if idle
- examples: (list commone xamples)
- destroy:
- when to use: actors that need to run once until completion. on crash, do not try to reschedule.
- when not to use: if you want your actor to have fault tolerance and be able to run transaprenlty to the underlying runner
- examples: batch jobs, image conversions, ephemeral jobs, (TODO come up with better eaxmples)
- restart:
- when to use: actors that should be running at all times
- when not to use: if you don't absolutely need something running at all times, since this consumes needless compute resources. considure using the scheduling api instead.
- examples: maintain outbound sockets, daemons, always-running jobs, (TODO come up with better examples)
the behavior for each is described below:
| Event | Restart | Sleep | Destroy |
|------------------------------|--------------|--------------|--------------|
| Graceful exit (StopCode::Ok) | Destroy | Destroy | Destroy |
| Crash (non-Ok exit) | Reschedule | Sleep | Destroy |
| Lost (runner disappeared) | Reschedule | Sleep | Destroy |
| Lost + force_reschedule | Reschedule | Reschedule | Reschedule |
| GoingAway (runner draining) | Reschedule | Sleep | Destroy |
| No capacity (allocation) | Queue (wait) | Sleep | Queue (wait) |
| No capacity + serverless | Queue (wait) | Queue (wait) | Queue (wait) |
| Wake signal (while sleeping) | Reschedule | Reschedule | Reschedule |
### inspector
- actors provide an inspector api to implement the:
- repl
- state read/write
- network inspector
- event log
- this is impelmented over a websocket over bare
### http api
- see the http api document on actors
### multi-region
- actors can be scheduled across multiple regions
- each actor has an actor id which embeds which region it lives in
- networking is automatically routed to the region that an actor lives in
- limitation: actors curretnly cannot migrate across regions
### backpressure
#### no runner capacity
- this is how actors with different crash policies behave when when there's backpressure:
- sleep = sleeps (sheds load by not rescheduling)
- restart = queues
- destroy = queues
- see the above matrix for more details on actor crash policy on how it handles no capacity.
- the actor queue is built to withstand high amounts of backpressure on rivet, so queueing actors is fine here
- a large queue means it'll take more time for your application to process the queue to catch up with demand when it comes online.
#### per-actor cpu & networking exhaustion
- actors are isolated, so they each have their own individual bottleneck. you can think of this like a process thread where each thread can only do so much.
- there is no durable message queue/"mailbox" for actors. if the actor cannot respond in time, then the request is dropped.
- if an actor exhauses its cpu or networking, then the runner
- returns service unavailble (503) if the actor fails to respond to a request in time
- there is no hard cap on the networking or cpu usage for each actor at the moment
- if your actor is resource intensive, it's common to use a separate mailbox actor to act as a queue
## runners
### regular vs serverless runners
there are 2 types of runners:
- regular: these are standard nodejs processes connected to rivet that rivet can orchestrate actors to and send network requests to at any time
- serverless: rivet works with serverless platforms. when an actor is created, it has a request-per-actor model where it opens a long-running request on the serverless platofrm to run a given actor.
### runner pool
- runners are pooled together by sharing a common name (ie "default")
- when an actor is created, it chooses the pool by selecting the runner name to run on
- rivet will automatically load balance actors across these runners
### runner key
- not relevnat for serverless runners
- each runner has a unique key that it provides when connecting. keys are unique to the instace the runner is running on and should be the same if the runner is restarted.
- this can be the: machine's ip, k8s pod name, etc
- if there is an existing runner connected with a given key, the runner will disconnect the old runner and replace it
- rivet is designed to handle network partitions by waiting for runners to miss a ping, indicating it's no longer alive. however, often times runners restart immediately after a hard crash and reconnect. in this case, the runner will reconnect on restart and terminate the old runner in order to prevent further actors from scheduling to the crashed runner.
### capacity
- not relevnat for serverless runners
- each runner can be assigned a capacity of how many actors it can run
- rivet will schedule with spread (not binpacking) in order to spread load over actors
#### usefulness of capacity = 1
- setting a capacity of 1 is helpful for situations where you have cpu-intensive apps that should not run with any other actors
- examples include game servers, ffmpeg jobs, etc
### versions & upgrading code
- each runner has a version index
- actors are always scheduled to the highest verison index (see runner priority below)
- this means that when a new runner is deployed:
1. runners with higher index come online
2. actors schedule to the highest index, stop scheduling to the older index
3. old index runners start draining and migrating actors to new index
4. all old runners are now shut down
- websocekts are live migrated to the new version when upgrading using hibernating websockets to users see no hiccup in their applications
- this is important because actors should never downgrade their runner. they should always move to a newer version of code in order to prevent corruption.
### runner scheduling prioroty
- actors are scheduled to runners sorted by priority of (version DESC, remaining capacity ASC)
### multi-region
TODO
### shutdown sequence
- runner shutdown is important to ensure that actors do not get unexpectedly terminated when either:
- upgrading your applciation and taking down old pods
- scaling down your runners horizontally (ie from an hpa)
- pressing ctrl-c when in development
- on shutdown:
1. tell rivet the runner is stopping
2. rivet tells all the actors on this runner to migrate
3. runner waits for all actors to finish migrating
4. runner exits process
### reconnection
- runners can handle temporary network partitions
- they'll automatically reconnect and replay missed commands/events between rivet and the runner
- this happens transparenlty to the user
- if disconnected for too long (indicating a network partition), the runner will shut itself down and exit
### autoscaling
- not relevant to serverless
- runners currently autoscale on cpu. more intelligent scaling is coming soon.
- tune your runner total slots capacity accordingly
- it's up to you to configure your hpa/etc to work like this. see the Connect guides (link to index page) for reference on hwo to configure this.
### serverless timeouts
- serverless runners take in to account the maximum run duration of the serverless platform
- the runners will mgirate actors to a new request before the request times out
- this is completely transparent to you and the user because of the fault tolerance and websocket migraiton characteristics
- it's common for actors to go sleep before hitting the serverless timeout
## networking
### web standards
- everything in rivet is built on webstandards by default
- nothing in rivet requires you to use our sdk, our sdks are meant to be a convenience. it's built to be as easy to use raw http/websocket endpoints from scratch.
- actions, events, etc are all built on simple, well-documented http/websocket under the hood (link to openapi & asyncapi docs).
- you can use low-level request handlers (lnk to dock) and low-level weboscket handlers (link to doc) to handle low-level primtivies yourself
### encoding
- rivetkit's action/events api supports communicating via [VBARE](link to github repo, see the blog post for the link), CBOR, or JSON
- VBARE: high-perofrmance & compact, optimal use case
- CBOR: descent encoding/decoding perf + portable libraries, good for implemnting high-ish performance on other platforms
- JSON: good for fast implementations & debugging (easy to read)
### tunneling
- when a runner connects it opens a tunnel to rivet to allow incoming traffic
- this is simila to systems like tailscale, ngrok, or other vpns
- we do this for security & configuraiton simplicity since it means that you don't have to manage exposing your rivetkit applications' networkig to rivet. instead, anything that can open a socket to rivet can accept inbound traffic to actors.
### gateway
- incoming traffic to actors come to the Rivet gateway and are routed to the appropriate runner
- the rivet gateway automatically handles:
- multi-region routing to route traffic to the correct reigon for an actor
- automatically waking the actor if needed
- sending traffic over the runner
### hibernating websockets
- hibernating web sockets are a core component of live actor migration & fault tolerance. it allows us to maintain an open websocket while the actor crashes, upgrades, or moves to another runner.
TODO: copy the rest of this from low-level webosckets document and rephrase
### actor health endpoin
- actors provide a simple, utility health endpoint at `/health` that lets you check if your actor is reachable (e.g. `curl https://api.rivet.dev/gateway/{actor id}/health`)
## multi-region
### networking
- actors may live in different regions than inbound requests
- Rivet uses the Epoxy (link again) system to handle global routing to route traffic to the correct region with high performance
- this is completely transparent to you. your app sends traffic to https://api.rivet.dev/gateway/* and it automatically routes to the correct actor in the appropriate region
### globally unique actor keys
- actor keys are globally unique to be able to benefit from multi-region capabilities without any extra work
- see more about globally uniuqe actor keys above
- see the actor keys document
### regional endpoints
- each reigon has a regional endpoint
- this endpoint is used specifically for connecting runners (for example https://api-us-east-1.rivet.dev), opt to use api.rivet.dev for all other traffic
- runners are required to connect to the regional endpoints
- this is because runners are sensitive to latency to the rivet regional datacenter
- we add datacenters regularly so each runner needs to be pinned to a single datacenter in order to ensure your availble datacneter list doesn't change sporadically without your consent
### persistence
- data is always persisted in the same region that is written
- this is important for minimal coldstarts & data locality laws
## namespaces
- rivet provides namespaces to run multiple actor systems in isolation
- this makes it really easy to have prod/staging environments or completely different applications running on the same rivet instance
- when you connect to rivet, you can specify which namespace you're connecting to
- self-hotsed rivet defaults to namespace "default"
- rivet cloud provdies isolated tokens for each namespace
## manager api
- rivet provides a standard rest api for managing actors
- useful endoints include:
- get /actors
- delete /actors/{}
- get /actors/names -> get all actor types available
## comparison to prior art for actors
### runtime
- there are very few serious actor implementation targeted at the javascirpt eocsystem. rivet is arguably the most serious open-source actor implementation for typescript out there.
### library vs orchestrator
- some actor systems opt to be purely a library while rivet opts to have an orchestrator (i.e. the single rust binary)
- this lets us to a lot of things other actor systems can't:
- separating orchestration, persistence, and proxy lets us isoalte the core to be incredibly reliable while the fast-changing applications that ocnnect to rivet can be more error-prone safely. with a library, the blast radius of your application also affects the entire actor system.
- support for serverless platforms to benefit from cost, multi-region, blitz scaling, and relibaiblity benefits
- optimize fault tolerance since we can make more assumtions about application state when the rivet core does not crash and your app does
### scheduling
actors is a loose term, but there are generally 2 types of schedulign in practice:
- ephemeral actors
- examples: erlang/otp, akka, swift
- provides no persistence or sleeping mechanism by defualt
- relies on supervisors for managing persistence
- [virtual actors](https://www.microsoft.com/en-us/research/project/orleans-virtual-actors/)
- an extension of the actor pattern that provides actors that can hibernate ("sleep") when not in use
- examples: orleans, dapr, durable objects
rivet has similarities with both to provide more flexibility:
- crash policies provdie for 3 types of actors:
- sleep -> most similar to virutal actors
- restart -> most similar to ephemeral actors but with a supervisor to auto-restart, however still has a durable queue ot handle backpressure
- crash -> most similar to traditional actors but with no supervisor to restart, however still has a durable queue to handle backpressure
### communication
- many actor frameworks use inbox patterns (think: queue-per-actor) to handle sending messages between actors
- there is no callback mechanims, instead you need to send messages back to the actual actor
- rivet opts to behave like web standards instead of using the message pattern
- actors can impelment the inbox pattern optionally
- but we provide lower-level networking to be able to be compatible with more techniologies
- rivet assumes the same serial concurerntly that other actors do (by the nature of javascript being single-threaded) but we allow you to run promises in parallel or handl eyour own concurrency control (which some other actor frameworks might require a spawning new actor to do)
_Source doc path: /docs/general/architecture_

View File

@@ -0,0 +1,18 @@
# Cross-Origin Resource Sharing
> Source: `src/content/docs/general/cors.mdx`
> Canonical URL: https://rivet.dev/docs/general/cors
> Description: Cross-Origin Resource Sharing (CORS) controls which origins (domains) can access your actors. When actors are exposed to the public internet, proper origin validation is critical to prevent security breaches and denial of service attacks.
---
Unlike stateless HTTP APIs that use CORS headers, Rivet Actors are stateful and support persistent WebSocket connections. Since WebSockets don't natively support CORS, we validate origins manually in the `onBeforeConnect` hook before connections may open.
## Implementing Origin Restrictions
To implement origin restrictions on Rivet Actors, use the `onBeforeConnect` hook to verify the request.
To catch the error on the client, use the following code:
See tracking issue for [configuring CORS per-actor on the gateway](https://github.com/rivet-dev/rivet/issues/3539) that will remove the need to implement origin restrictions in `onBforeRequest`.
_Source doc path: /docs/general/cors_

View File

@@ -0,0 +1,51 @@
# Documentation for LLMs & AI
> Source: `src/content/docs/general/docs-for-llms.mdx`
> Canonical URL: https://rivet.dev/docs/general/docs-for-llms
> Description: Rivet provides optimized documentation formats specifically designed for Large Language Models (LLMs) and AI integration tools.
---
## Skills (Recommended)
For AI coding assistants like Claude Code, Cursor, or Windsurf, install Rivet skills for the best development experience:
```sh
npx skills add rivet-dev/skills
```
Skills provide your AI assistant with Rivet-specific knowledge, best practices, and code patterns directly in your project context.
## Available Formats
### `llms.txt` (Condensed)
A condensed version of the documentation perfect for quick reference and context-aware AI assistance.
**Access:** <a href="/llms.txt" target="_blank">/llms.txt</a>
This format includes:
- Key concepts and features
- Essential getting started information
- Summaries of main functionality
- Optimized for token efficiency
### `llms-full.txt` (Complete)
The complete documentation in a single file, ideal for comprehensive AI assistance and in-depth analysis.
**Access:** <a href="/llms-full.txt" target="_blank">/llms-full.txt</a>
This format includes:
- Complete documentation content
- All examples and detailed explanations
- Full API references and guides
- Suitable for complex queries and comprehensive understanding
## Access Pages As Markdown
Each documentation page is also available as clean markdown by appending `.md` to any documentation URL path.
For example:
- Original URL: `https://rivet.dev/docs/actors`
- Markdown URL: `https://rivet.dev/docs/actors.md`
_Source doc path: /docs/general/docs-for-llms_

View File

@@ -0,0 +1,24 @@
# Edge Networking
> Source: `src/content/docs/general/edge.mdx`
> Canonical URL: https://rivet.dev/docs/general/edge
> Description: Actors automatically run near your users on your provider's global network.
---
At the moment, edge networking is only supported on Rivet Cloud & Cloudflare Workers. More self-hosted platforms are on the roadmap.
## Region selection
### Automatic region selection
By default, actors will choose the nearest region based on the client's location.
Under the hood, Rivet and Cloudflare use [Anycast routing](https://en.wikipedia.org/wiki/Anycast) to automatically find the best location for the client to connect to without relying on a slow manual pinging process.
### Manual region selection
The region an actor is created in can be overridden using region options:
See [Create Manage Actors](/docs/actors/communicating-between-actors) for more information.
_Source doc path: /docs/general/edge_

View File

@@ -0,0 +1,98 @@
# Endpoints
> Source: `src/content/docs/general/endpoints.mdx`
> Canonical URL: https://rivet.dev/docs/general/endpoints
> Description: Configure how your backend connects to Rivet and how clients reach your actors.
---
## Local Development
No configuration is needed for local development. RivetKit runs entirely on your local machine without any extra configuration to run Rivet Actors.
## Production Deployment
When deploying to production, you need to configure endpoints so your backend can communicate with Rivet Engine and clients can reach your actors.
<img src={imgEndpointEnvVars.src} alt="Diagram showing Client connecting to Rivet, which connects to Your Backend" />
### Private Endpoint
The private endpoint tells your backend where to find the Rivet Engine.
### Environment Variable
```bash
RIVET_ENDPOINT=https://my-namespace:sk_xxxxx@api.rivet.dev
```
### Config
### Public Endpoint
The public endpoint tells clients where to connect to reach your actors.
This endpoint and token will be exposed to the internet. Use a public token (`pk_`), not your secret token (`sk_`).
The public endpoint is only required if using the [serverless runtime mode](/docs/general/runtime-modes#runners) and if you have a frontend using RivetKit.
### Environment Variable
```bash
RIVET_PUBLIC_ENDPOINT=https://my-namespace:pk_xxxxx@api.rivet.dev
```
### Config
## Advanced
### URL Auth Syntax
Endpoint URLs support embedding namespace and token directly in the URL:
```
https://namespace:token@host/path
```
This is the recommended approach for simplicity. Alternatively, you can use separate environment variables:
```bash
RIVET_ENDPOINT=https://api.rivet.dev
RIVET_NAMESPACE=my-namespace
RIVET_TOKEN=sk_xxxxx
```
### Security
In serverless mode, the private endpoint is used to validate that requests to `GET /api/rivet/start` are coming from your trusted Rivet endpoint. If the private endpoint is not configured, anyone can run a self-hosted instance of Rivet and connect to your backend from any endpoint.
### How Clients Connect
This flow applies to [serverless runtime mode](/docs/general/runtime-modes#serverless). For [runner runtime mode](/docs/general/runtime-modes#runners) or [clients configured to connect directly to Rivet](/docs/clients/javascript), clients connect directly to Rivet and this metadata flow is not needed.
When a client connects to your serverless application, it follows this flow:
1. Client makes a request to `https://my-app.example.com/api/rivet/metadata`
2. Your app returns the public endpoint configuration:
```json
{
"clientEndpoint": "https://api.rivet.dev",
"clientNamespace": "my-namespace",
"clientToken": "pk_xxxxx"
}
```
3. Client caches these values and uses them for subsequent requests
4. Client connects to `https://api.rivet.dev/gateway/{actor}`, which routes requests to your actors
This indirection exists because Rivet acts as a gateway between clients and your actors. This is because Rivet handles routing, load balancing, and actor lifecycle management of actors.
## Reference
| Environment Variable | Config Option | Description |
|---------------------|---------------|-------------|
| `RIVET_ENDPOINT` | `endpoint` | Rivet Engine URL for your backend |
| `RIVET_NAMESPACE` | `namespace` | Namespace for actor isolation |
| `RIVET_TOKEN` | `token` | Authentication token for engine connection |
| `RIVET_PUBLIC_ENDPOINT` | `serverless.publicEndpoint` | Client-facing endpoint |
| `RIVET_PUBLIC_TOKEN` | `serverless.publicToken` | Client-facing token |
_Source doc path: /docs/general/endpoints_

View File

@@ -0,0 +1,87 @@
# Environment Variables
> Source: `src/content/docs/general/environment-variables.mdx`
> Canonical URL: https://rivet.dev/docs/general/environment-variables
> Description: This page documents all environment variables that configure RivetKit behavior.
---
## Connection
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_ENDPOINT` | Endpoint URL to connect to Rivet Engine. Supports [URL auth syntax](/docs/general/endpoints#url-auth-syntax). |
| `RIVET_TOKEN` | Authentication token for Rivet Engine |
| `RIVET_NAMESPACE` | Namespace to use (default: "default") |
## Public Endpoint
These variables configure how clients connect to your actors.
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_PUBLIC_ENDPOINT` | Public endpoint for client connections. Supports [URL auth syntax](/docs/general/endpoints#url-auth-syntax). |
| `RIVET_PUBLIC_TOKEN` | Public token for client authentication |
## Runner Configuration
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_RUNNER` | Runner name (default: "default") |
| `RIVET_RUNNER_VERSION` | Version number for the runner. See [Versions & Upgrades](/docs/actors/versions). |
| `RIVET_RUNNER_KIND` | Type of runner |
| `RIVET_TOTAL_SLOTS` | Total actor slots available (default: 100000) |
## Engine
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_RUN_ENGINE` | Set to `1` to spawn the engine process |
| `RIVET_RUN_ENGINE_HOST` | Host to bind the spawned local engine process to. Defaults to `127.0.0.1`. |
| `RIVET_RUN_ENGINE_PORT` | Port to bind the spawned local engine process to. Defaults to `6420`. |
| `RIVET_RUN_ENGINE_VERSION` | Version of engine to download |
## Inspector
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_INSPECTOR_DISABLE` | Set to `1` to disable the inspector |
## Metrics
| Environment Variable | Description |
|---------------------|-------------|
| `_RIVET_METRICS_TOKEN` | Bearer token that gates the per-actor Prometheus `/metrics` endpoint. When unset, `/metrics` is disabled. |
## Experimental
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_EXPERIMENTAL_OTEL` | Set to `1` to enable experimental OTel tracing in Rivet Actors |
## Storage
| Environment Variable | Description |
|---------------------|-------------|
| `RIVETKIT_RUNTIME` | Runtime binding to use for RivetKit core: `auto`, `native`, or `wasm`. Defaults to `auto`. |
| `RIVETKIT_STORAGE_PATH` | Overrides the default file-system storage path used by RivetKit when using the default driver. |
## Lifecycle
| Environment Variable | Description |
|---------------------|-------------|
| `RIVETKIT_RUNTIME_MODE` | Controls how `registry.start()` runs. Accepted values are `envoy` and `serverless`; any other explicit value errors. Defaults to `envoy`: opens a long-lived WebSocket to the engine (Mode A). Set to `serverless` to bind an HTTP listener via `registry.listen()` (Mode B). |
| `RIVETKIT_PUBLIC_DIR` | Directory of static assets to serve alongside the framework routes when calling `registry.listen()`. Used as a fallback when `opts.publicDir` is not passed. On auto-listen via `registry.start()`, defaults to `/public` when this env var is unset. |
| `RIVET_PORT` | Port the listener binds when calling `registry.listen()` without an explicit `opts.port`. Must be an integer between 1 and 65535. Defaults to `3000`. |
## Logging
| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_LOG_LEVEL` | Log level: `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` |
| `RIVET_LOG_TARGET` | Set to `1` to include log target |
| `RIVET_LOG_TIMESTAMP` | Set to `1` to include timestamps |
| `RIVET_LOG_MESSAGE` | Set to `1` to include message formatting |
| `RIVET_LOG_ERROR_STACK` | Set to `1` to include error stack traces |
| `RIVET_LOG_HEADERS` | Set to `1` to log request headers |
_Source doc path: /docs/general/environment-variables_

View File

@@ -0,0 +1,96 @@
# HTTP Server
> Source: `src/content/docs/general/http-server.mdx`
> Canonical URL: https://rivet.dev/docs/general/http-server
> Description: Different ways to run your RivetKit HTTP server.
---
## Methods of Running Your Server
### registry.start()
The simplest way to run your server. Starts a local RivetKit server, serves static files from a `public` directory, and starts the actor runner:
Run with `npx tsx --watch index.ts` (Node.js), `bun --watch index.ts` (Bun), or `deno run --allow-net --allow-read --allow-env --watch index.ts` (Deno). Clients connect to the Rivet Engine on `http://localhost:6420`.
### With Fetch Handlers
A [fetch handler](https://wintercg.org/) is a function that takes a `Request` and returns a `Response`. This is the standard pattern used by Cloudflare Workers, Deno Deploy, Bun, and other modern runtimes.
Use `registry.serve()` to get a fetch handler:
To integrate with a router like [Hono](https://hono.dev/) or [Elysia](https://elysiajs.com/), use `registry.handler()`:
### Hono
### Elysia
Then run your server:
```bash Node.js
npx tsx --watch server.ts
```
```bash Bun
bun --watch server.ts
```
```bash Deno
deno run --allow-net --allow-read --allow-env --watch server.ts
```
### Explicit HTTP Server
If you need to explicitly start the HTTP server instead of using the fetch handler pattern:
### Node.js (Hono)
Using Hono with `@hono/node-server`:
### Node.js (Adapter)
Using `@whatwg-node/server` to adapt the fetch handler to Node's HTTP server:
```ts server.ts @nocheck
import { actor, setup } from "rivetkit";
import { createServer } from "node:http";
import { createServerAdapter } from "@whatwg-node/server";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
const handler = createServerAdapter(registry.serve().fetch);
const server = createServer(handler);
server.listen(3000);
```
### Bun
Using Bun's native server:
```ts server.ts @nocheck
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
Bun.serve({
port: 3000,
fetch: (request: Request) => registry.handler(request),
});
```
### Deno
Using Deno's native server:
```ts server.ts @nocheck
import { actor, setup } from "rivetkit";
const myActor = actor({ state: {}, actions: {} });
const registry = setup({ use: { myActor } });
Deno.serve({ port: 3000 }, (request: Request) => registry.handler(request));
```
_Source doc path: /docs/general/http-server_

View File

@@ -0,0 +1,74 @@
# Logging
> Source: `src/content/docs/general/logging.mdx`
> Canonical URL: https://rivet.dev/docs/general/logging
> Description: Actors provide a built-in way to log complex data to the console.
---
Using the context's log object (`c.log`) allows you to log complex data using structured logging.
Using the actor logging API is completely optional.
## Log levels
There are 7 log levels:
| Level | Call | Description |
| ------ | ------------------------------- | ---------------------------------------------------------------- |
| Fatal | `c.log.fatal(message, ...args);` | Critical errors that prevent core functionality |
| Error | `c.log.error(message, ...args);` | Errors that affect functionality but allow continued operation |
| Warn | `c.log.warn(message, ...args);` | Potentially harmful situations that should be addressed |
| Info | `c.log.info(message, ...args);` | General information about significant events & state changes |
| Debug | `c.log.debug(message, ...args);` | Detailed debugging information, usually used in development |
| Trace | `c.log.trace(message, ...args);` | Very detailed debugging information, usually for tracing flow |
| Silent | N/A | Disables all logging output |
## Structured logging
The built-in logging API (using `c.log`) provides structured logging to let you log key-value
pairs instead of raw strings. Structured logs are readable by both machines &
humans to make them easier to parse & search.
When using `c.log`, the actor's name, key, and actor ID are automatically included in every log output. This makes it easy to filter and trace logs by specific actors in production environments.
### Examples
The logging system is built on [Pino](https://getpino.io/#/docs/api?id=logger), a high-performance structured logger for Node.js.
## Configuration
### Environment Variables
You can configure logging behavior using environment variables:
| Variable | Description | Values | Default |
| -------- | ----------- | ------ | ------- |
| `RIVET_LOG_LEVEL` | Sets the minimum log level to display | `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` | `warn` |
| `RIVET_LOG_TARGET` | Include the module name that logged the message | `1` to enable, `0` to disable | `0` |
| `RIVET_LOG_TIMESTAMP` | Include timestamp in log output | `1` to enable, `0` to disable | `0` |
| `RIVET_LOG_MESSAGE` | Enable detailed message logging for debugging | `1` to enable, `0` to disable | `0` |
| `RIVET_LOG_ERROR_STACK` | Include stack traces in error output | `1` to enable, `0` to disable | `0` |
| `RIVET_LOG_HEADERS` | Log HTTP headers in requests | `1` to enable, `0` to disable | `0` |
Example:
```bash
RIVET_LOG_LEVEL=debug RIVET_LOG_TARGET=1 RIVET_LOG_TIMESTAMP=1 node server.js
```
### Log Level
You can configure the log level programmatically when setting up your registry:
### Custom Pino Logger
You can also provide a custom Pino base logger for more advanced logging configurations:
If using a custom base logger, you must manually configure your own log level in the Pino logger.
For more advanced Pino configuration options, see the [Pino API documentation](https://getpino.io/#/docs/api?id=export).
### Disable Welcome Message
You can disable the default RivetKit welcome message with:
_Source doc path: /docs/general/logging_

View File

@@ -0,0 +1,119 @@
# Pool Configuration
> Source: `src/content/docs/general/pool-configuration.mdx`
> Canonical URL: https://rivet.dev/docs/general/pool-configuration
> Description: Reference for runner pool configuration, including drain behavior, actor eviction rate limiting, and serverless-specific options.
---
A **runner pool** is the set of runners Rivet manages for a given runner name within a namespace. The pool configuration controls how runners are scaled, drained on version upgrades, and how quickly actors are evicted from drained runners.
There are two pool kinds:
- **`normal`** — runners connect to the engine themselves (for example a long-running process started by you, Docker, or Kubernetes). The engine does not start or stop runners.
- **`serverless`** — the engine calls an HTTP endpoint to wake runners on demand. Used by serverless platforms (Vercel, Cloudflare Workers, Freestyle, etc.). See [Runtime Modes](/docs/general/runtime-modes).
## Setting the Configuration
Configure a pool from the [Rivet dashboard](https://dashboard.rivet.dev) under your namespace's runner settings. The dashboard is the recommended way to manage pool configuration.
You can also set pool configuration directly through the API or the TypeScript SDK:
```typescript SDK @nocheck
import { RivetClient } from "@rivetkit/engine-api-full";
const rivet = new RivetClient({
environment: "https://api.rivet.dev",
token: process.env.RIVET_TOKEN!,
});
await rivet.runnerConfigsUpsert("default", {
namespace: "default",
datacenters: {
default: {
serverless: {
url: "https://my-app.example.com/api/rivet",
requestLifespan: 60 * 15,
actorEvictionDelay: 5,
actorEvictionPeriod: 60,
actorEvictionRate: 1,
},
},
},
});
```
```bash curl
curl -X PUT "https://api.rivet.dev/runner-configs/default?namespace=default" \
-H "Authorization: Bearer $RIVET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"datacenters": {
"default": {
"serverless": {
"url": "https://my-app.example.com/api/rivet",
"request_lifespan": 900,
"actor_eviction_delay": 5,
"actor_eviction_period": 60,
"actor_eviction_rate": 1
}
}
}
}'
```
The HTTP API uses `snake_case`. The TypeScript SDK uses `camelCase`. The field names below use `camelCase`.
## Common Options
These options apply to both `normal` and `serverless` pools.
| Option | Type | Default | Description |
|---|---|---|---|
| `drainOnVersionUpgrade` | `bool` | `true` | When a new runner version is deployed, stop old runners and migrate their actors. See [Versions & Upgrades](/docs/actors/versions#drain-on-version-upgrade). |
| `actorEvictionDelay` | `u32` (seconds) | `0` | Delay before actor eviction begins after a drain is triggered. Gives clients time to receive the drain signal before migrations start. |
| `actorEvictionPeriod` | `u32` (seconds) | `0` | Window over which evictions are batched. Used together with `actorEvictionRate` to smooth eviction load on the rest of the pool. |
| `actorEvictionRate` | `f32` (actors/sec) | `1.0` | Maximum number of actors evicted per second once eviction is underway. Set higher for fast cutovers, lower to spread reschedule load. |
| `metadata` | `object` | — | Arbitrary JSON metadata attached to the pool. Useful for tagging and dashboards. |
### Tuning eviction rate limiting
Eviction kicks in whenever a runner is drained — most commonly during a version upgrade with `drainOnVersionUpgrade: true`, but also when a runner disconnects ungracefully or is replaced.
A typical tuning starts from:
- `actorEvictionDelay: 5` — five-second head start so clients see the drain notification before migrations begin.
- `actorEvictionPeriod: 60` — batch over a one-minute window.
- `actorEvictionRate: 1` — evict one actor per second.
Increase `actorEvictionRate` for small pools where a full cutover finishes in seconds. Decrease it for large pools to avoid bursts of reschedule traffic.
## Serverless-Only Options
These options only apply when `kind: "serverless"`.
| Option | Type | Default | Description |
|---|---|---|---|
| `url` | `string` | — | HTTP endpoint the engine calls to wake a runner. |
| `headers` | `map<string, string>` | `{}` | Additional headers sent with the wake request (for example an auth token). |
| `requestLifespan` | `u32` (seconds) | — | Total lifespan of a serverless request before drain begins. Must be shorter than your platform's request timeout. |
| `maxConcurrentActors` | `u64` | `1000` | Soft cap on concurrent actors hosted across the pool. |
| `drainGracePeriod` | `u32` (seconds) | `1800` (30 min) | Time a serverless runner reserves at the end of its lifespan for actors to stop gracefully. |
| `metadataPollInterval` | `u64` (ms) | engine default | How often each runner re-fetches pool metadata to detect new versions. |
### Deprecated options
The following options still parse for backwards compatibility but should not be used in new configurations:
- `slotsPerRunner`
- `minRunners`
- `maxRunners`
- `runnersMargin`
## Related
- [Runtime Modes](/docs/general/runtime-modes) — runner vs serverless behavior.
- [Versions & Upgrades](/docs/actors/versions) — how `drainOnVersionUpgrade` interacts with version detection.
- [Limits](/docs/actors/limits) — request lifespan and drain grace period limits.
- [Debugging](/docs/actors/debugging) — inspect a pool configuration via the API.
_Source doc path: /docs/general/pool-configuration_

View File

@@ -0,0 +1,98 @@
# Production Checklist
> Source: `src/content/docs/general/production-checklist.mdx`
> Canonical URL: https://rivet.dev/docs/general/production-checklist
> Description: Checklist for deploying Rivet Actors to production.
---
We recommend passing this page to your coding agent to verify your configuration before deploying.
## Environment
- **Set `NODE_ENV=production`.** Ensures optimized performance and disables development-only behavior.
- **Ensure log level is not set to debug.** Leave `RIVET_LOG_LEVEL` at its default or explicitly set it to `warn` to avoid excessive logging. See [Logging](/docs/general/logging).
- **Do not set `RIVET_EXPOSE_ERRORS=1` in production.** This exposes internal error details to clients. It is automatically enabled when `NODE_ENV=development`. See [Errors](/docs/actors/errors).
## Runtime Mode
- **Configure a runner version.** Required for graceful upgrades and draining of old actors. Applies to both serverless and runner modes. See [Versions & Upgrades](/docs/actors/versions).
### Serverless
- **Check platform timeouts.** Rivet handles migration between invocations automatically, but shorter timeouts increase migration frequency. See [Timeouts](/docs/general/runtime-modes#timeouts).
- **Verify `/api/rivet/start` body size limits.** Serverless actor starts carry actor config and preloaded KV or SQLite startup data in the request body. Keep `serverless.maxStartPayloadBytes` and your platform or proxy body limit at **16 MiB or higher**, or lower the preload budget if your platform cannot accept that size. See [Limits](/docs/actors/limits#kv-preloading).
- **Configure max runners.** Go to Settings > Providers > Edit Provider > Max Runners to set the limit. The default is 100,000 runners. This is effectively your max actor count.
- **Verify your platform rate limit accommodates your actor create and wake frequency.** Actor start requests are sent from Rivet's servers, so they all originate from the same IP. Per-IP rate limits will throttle the engine well before they would throttle real end-user traffic. Size your platform's rate limit to your peak actor create and wake rate, not your end-user request rate.
- **Set the per-instance max concurrent actor limit.** Each serverless instance hosts one actor per in-flight `/api/rivet/start` request, so your platform's per-instance concurrency (e.g. GCP Cloud Run `--concurrency`, AWS Lambda reserved concurrency, Vercel `maxDuration` + concurrency) directly caps actors per instance. Pick a value based on per-actor memory and CPU; the platform autoscales out additional instances once existing ones hit the cap.
- **Tune `requestLifespan` to your platform's hard request timeout.** `requestLifespan` (default `3600`, 60 minutes) is the total lifespan of each serverless request before actors migrate to a fresh instance. Set it just below your platform's hard timeout (e.g. `295` for Vercel Hobby, `3595` for Vercel Pro, `840` for Cloud Run's 15-min cap). Configure via [`configurePool`](/docs/general/registry-configuration). See [Timeouts](/docs/general/runtime-modes#timeouts).
- **Tune `drainGracePeriod` to cover graceful actor shutdown.** Time reserved at the end of `requestLifespan` for actors to stop gracefully before the request is forcibly closed. Default is 30 minutes from the engine; lower it for short-lived stateless actors, raise it if your actors do non-trivial cleanup or final SQLite writes. Configure via [`configurePool`](/docs/general/registry-configuration). See [Limits](/docs/actors/limits).
### Runner
- **Set a graceful shutdown period of at least 35 minutes.** Runners need up to 30 minutes to drain actors during upgrades, plus buffer for shutdown overhead. In Kubernetes, set `terminationGracePeriodSeconds: 2100` on the pod spec.
## Actors
### Design Patterns
- **Do not use god actors.** Avoid putting all logic into a single actor type. See [Design Patterns](/docs/actors/design-patterns).
- **Do not use actor-per-request patterns.** Avoid creating a new actor for each request. See [Design Patterns](/docs/actors/design-patterns).
### Lifecycle
- **Do not rely on `onSleep` for critical cleanup.** `onSleep` is not called during crashes or forced terminations. See [Lifecycle](/docs/actors/lifecycle).
### State
- **Verify `c.state` does not grow unbounded.** Avoid using arrays or objects that grow over time in state. Use [SQLite](/docs/actors/sqlite) for unbounded or append-heavy data instead.
- **Verify actor data does not exceed 10 GB.** Contact [enterprise support](https://rivet.dev/sales) if you need more storage.
- **Use input parameters and `createState` for actor initialization.** See [Input Parameters](/docs/actors/input).
### Events
- **Use `conn.send()` instead of `c.broadcast()` for private events.** `c.broadcast()` sends to all connected clients. Use `conn.send()` to send events to a specific connection. See [Realtime](/docs/actors/events).
### Actions
- **Review action timeout configuration.** The default `actionTimeout` is 60 seconds. Increase it if you have long-running actions like API calls or file processing. See [Actor Configuration](/docs/general/actor-configuration).
- **Review message size limits.** The default `maxIncomingMessageSize` is 64 KiB and `maxOutgoingMessageSize` is 1 MiB. Increase if your actors send or receive large JSON payloads. See [Registry Configuration](/docs/general/registry-configuration).
### Queues
- **Review queue limits.** The default `maxQueueSize` is 1,000 messages and `maxQueueMessageSize` is 64 KiB. Increase if you expect burst traffic or large queue payloads. See [Actor Configuration](/docs/general/actor-configuration).
- **Ensure queue handlers are idempotent.** If processing fails before `message.complete()`, the message will be retried. See [Queues](/docs/actors/queues).
### Workflows
- **Verify workflows do not generate infinite steps.** Use `ctx.loop` to avoid creating unbounded step histories. See [Workflows](/docs/actors/workflows).
## Security
### Authentication
- **Validate connections in `createConnState` or `onBeforeConnect`.** Do not trust client input without validation. See [Authentication](/docs/actors/authentication).
### CORS
- **Configure CORS for production.** Restrict allowed origins instead of allowing all. See [CORS](/docs/general/cors).
### Tokens (Rivet Cloud)
- **Use `pk_*` tokens for `RIVET_PUBLIC_ENDPOINT`.** Public tokens are safe to expose to clients.
- **Use `sk_*` tokens for `RIVET_ENDPOINT`.** Secret tokens should only be used server-side.
- **Do not leak your secret token.** Never expose `sk_*` tokens in client-side code, public repositories, or browser environments. See [Endpoints](/docs/general/endpoints).
- **Verify you're connecting to the correct region.** Use the nearest datacenter endpoint (e.g. `api-us-west-1.rivet.dev`) for lowest latency.
### Access Control
Access control is only needed if you want granular permissions for different clients. For most use cases, basic authentication in `onBeforeConnect` or `createConnState` is sufficient.
- **Use deny-by-default rules.** Reject unknown roles in `onBeforeConnect`, action handlers, `canPublish`, and `canSubscribe`. See [Access Control](/docs/actors/access-control).
- **Authorize actions explicitly.** Check the caller's role in each action handler and throw `forbidden` for unauthorized access.
- **Gate event subscriptions and queue publishes.** Use `canSubscribe` and `canPublish` hooks to restrict which clients can subscribe to events or publish to queues.
## Clients
- **Dispose connections and/or client when not in use (JavaScript client).** Call `conn.dispose()` or `client.dispose()` when no longer needed to free resources. React and SwiftUI clients handle this automatically. See [Connection Lifecycle](/docs/clients/javascript#connection-lifecycle).
_Source doc path: /docs/general/production-checklist_

View File

@@ -0,0 +1,32 @@
# Registry Configuration
> Source: `src/content/docs/general/registry-configuration.mdx`
> Canonical URL: https://rivet.dev/docs/general/registry-configuration
> Description: This page documents the configuration options available when setting up a RivetKit registry. The registry configuration is passed to the `setup()` function.
---
## Example Configurations
### Basic Setup
### Connecting to Rivet Engine
## Starting Your App
After configuring your registry, start it:
See [Runtime Modes](/docs/general/runtime-modes) for details on when to use each mode.
## Environment Variables
Many configuration options can be set via environment variables. See [Environment Variables](/docs/general/environment-variables) for a complete reference.
## Configuration Reference
## Related
- [Actor Configuration](/docs/general/actor-configuration): Configure individual actors
- [HTTP Server Setup](/docs/general/http-server): Set up HTTP routing and middleware
- [Architecture](/docs/general/architecture): Understand how RivetKit works
_Source doc path: /docs/general/registry-configuration_

View File

@@ -0,0 +1,99 @@
# Runtime Modes
> Source: `src/content/docs/general/runtime-modes.mdx`
> Canonical URL: https://rivet.dev/docs/general/runtime-modes
> Description: RivetKit supports two runtime modes for running your actors:
---
- **Serverless**: Default mode. Responds to HTTP requests and scales automatically.
- **Runners**: Background processes without HTTP endpoints. Only needed for advanced scenarios.
## Serverless
Serverless is the default and recommended mode. Rivet sends HTTP requests to your backend to run actor logic, allowing your infrastructure to scale automatically.
### Benefits
- **Platform support**: Works with serverless platforms (Vercel, Cloudflare Workers, etc.)
- **Scale to zero**: No cost when idle
- **Edge deployments**: Easier to deploy to edge locations
- **Preview deployments**: Integrates with preview deployments on platforms like Vercel and Railway
- **Efficient autoscaling**: Request-based autoscaling can be faster and more efficient than CPU-based autoscaling depending on the platform
### Example
See [Server Setup](/docs/general/http-server/) for more configuration options.
### Architecture
When a client creates an actor, it sends a request to the Rivet Engine. The engine then calls `GET /api/rivet/start` on your serverless backend to run the actor.
<img src={imgServerless.src} alt="Serverless architecture diagram" />
### Advanced
#### Endpoints
Rivet exposes the following endpoints:
- `GET /api/rivet/metadata`: Validates configuration
- `GET /api/rivet/start`: Runs an actor
You should never call these endpoints yourself, this is included purely for comprehension of how Rivet works under the hood.
#### Timeouts
Serverless platforms like Vercel have function timeouts. Rivet handles this automatically by migrating actors between function invocations, preserving state through `ctx.state`. Write your code as if it runs forever, Rivet handles the rest.
Read more about [how we handle timeouts](/blog/2025-10-20-how-we-built-websocket-servers-for-vercel-functions/#timeouts-and-failover).
#### Shutdown Sequence
Each serverless request has a configurable lifespan (`requestLifespan`, default: 60 minutes). Set this to match your platform's function timeout (e.g. `requestLifespan: 3600` for Vercel Pro).
When the request nears its lifespan, the engine reserves a grace period (`serverless_drain_grace_period`, default: 10 seconds) at the end to gracefully stop actors. For example, with a 3600-second lifespan, actors begin stopping at 3590 seconds. After the full lifespan elapses, the connection is forcibly closed and any remaining actors are rescheduled.
See [Limits](/docs/actors/limits#serverless-shutdown) for configuration details.
## Runners
Runners run actors as long-running background processes without exposing an HTTP endpoint.
### When to Use Runners
- **No HTTP server**: Your app does not or cannot expose an HTTP server
- **No load balancer**: You don't have a load balancer to distribute HTTP requests across your servers
- **Custom scaling**: You have custom scaling requirements
### Example
The runner runs in the background, ready to run actors.
### Architecture
On startup, your backend calls `registry.startEnvoy()` which opens a persistent connection to the Rivet Engine. When a client creates an actor, the engine sends a command through this connection to start the actor on your backend.
<img src={imgRunners.src} alt="Runners architecture diagram" />
### Configuration
#### Runner Pool
Use `RIVET_RUNNER` to assign runners to a pool. This lets you control which runners handle specific actors.
```bash
RIVET_RUNNER=gpu-workers
```
See [Pool Configuration](/docs/general/pool-configuration) for how pools are scaled, drained on version upgrades, and rate-limited during actor eviction.
## Comparison
| Mode | Method | Use Case |
|------|--------|----------|
| Auto | `registry.start()` | Simplest setup. Starts server, serves static files, and runs actors. |
| Serverless | `registry.serve()` | Fetch handler for serverless platforms |
| Serverless | `registry.handler()` | Integrating with existing routers (Hono, Elysia, etc.) |
| Runner | `registry.startEnvoy()` | Long-running processes without HTTP endpoints |
_Source doc path: /docs/general/runtime-modes_

View File

@@ -0,0 +1,79 @@
# WASM vs Native SDK
> Source: `src/content/docs/general/wasm-vs-native-sdk.mdx`
> Canonical URL: https://rivet.dev/docs/general/wasm-vs-native-sdk
> Description: RivetKit runs your actors on a native or a WebAssembly runtime depending on your platform.
---
RivetKit ships two runtimes for executing actor logic. Most projects use the
native runtime automatically. Edge and serverless platforms that cannot run
native binaries use the WebAssembly runtime.
- **Native**: Default. Runs on Node.js and Bun via native bindings. Best performance.
- **WebAssembly (wasm)**: Runs anywhere a `WebAssembly.Module` can be instantiated, including Cloudflare Workers, Supabase Edge Functions, and Deno Deploy.
## Native runtime
The native runtime is the default and requires no configuration. It loads
platform-specific native bindings for the best performance and full feature
support on Node.js and Bun.
## WebAssembly runtime
Edge platforms run on isolates (V8, Deno) that cannot load native binaries, so
RivetKit provides a WebAssembly build of its core runtime in the
`@rivetkit/rivetkit-wasm` package. You select it with `runtime: "wasm"` and pass
the wasm bindings and binary through the `wasm` option.
### Recommended: use a platform package
For supported platforms, use the dedicated package instead of wiring the wasm
runtime by hand. They install the wasm runtime, load the binary, and (on
Cloudflare) provide the outbound WebSocket the engine tunnel needs.
- **Cloudflare Workers**: [`@rivetkit/cloudflare-workers`](/docs/actors/quickstart/cloudflare)
- **Supabase Edge Functions**: [`@rivetkit/supabase`](/docs/actors/quickstart/supabase)
```typescript @nocheck
// Cloudflare Workers
import { actor } from "rivetkit";
import { createHandler } from "@rivetkit/cloudflare-workers";
const counter = actor({ state: { count: 0 }, actions: {} });
export default createHandler({ use: { counter } });
```
### Manual configuration
For platforms without a dedicated package, configure the wasm runtime directly.
Pass the bindings from `@rivetkit/rivetkit-wasm` and the wasm binary as
`initInput`. `initInput` accepts a `Uint8Array`, `URL`, `Response`, or a
`WebAssembly.Module`.
```typescript @nocheck
import { actor, setup } from "rivetkit";
import * as wasmBindings from "@rivetkit/rivetkit-wasm";
import wasmModule from "@rivetkit/rivetkit-wasm/rivetkit_wasm_bg.wasm";
const counter = actor({ state: { count: 0 }, actions: {} });
const registry = setup({
runtime: "wasm",
wasm: { bindings: wasmBindings, initInput: wasmModule },
use: { counter },
});
```
On platforms without an outbound `new WebSocket(url)` constructor (such as
Cloudflare Workers), you must also install a fetch-based `globalThis.WebSocket`
shim so the actor can open its tunnel to the engine. The platform packages handle
this for you, which is why they are recommended.
## Related
- [Runtime Modes](/docs/general/runtime-modes)
- [Cloudflare Workers Quickstart](/docs/actors/quickstart/cloudflare)
- [Supabase Functions Quickstart](/docs/actors/quickstart/supabase)
_Source doc path: /docs/general/wasm-vs-native-sdk_