Skip to main content
More

Limits

Review Rivet Actors limits for state, messages, connections, execution, and storage so applications stay within supported bounds.

This page documents the limits for Rivet Actors.

There are two types of limits:

  • Soft Limit: Application-level limit, configurable in RivetKit. These cannot exceed the hard limit.
  • Hard Limit: Infrastructure-level limit that cannot be configured.

Soft limits are configured in two places. Registry-level WebSocket message-size limits are passed to setup:

import { setup } from "rivetkit";

const rivet = setup({
  use: { /* ... */ },
  maxIncomingMessageSize: 1_048_576,
  maxOutgoingMessageSize: 10_485_760,
});

Per-actor limits such as queue sizes and lifecycle timeouts are passed to actor(...) via options:

import { actor } from "rivetkit";

const myActor = actor({
  options: {
    maxQueueSize: 1000,
    actionTimeout: 60_000,
    stateSaveInterval: 1_000,
  },
  // ...
});

Limits

WebSocket

These limits affect actions that use .connect() and low-level WebSockets.

NameSoft LimitHard LimitDescription
Max incoming message size64 KiB16 MiBMaximum size of incoming WebSocket messages. Soft limit configurable via maxIncomingMessageSize.
Max outgoing message size1 MiB16 MiBMaximum size of outgoing WebSocket messages. Soft limit configurable via maxOutgoingMessageSize.
WebSocket open timeoutN/A15 secondsTime allowed to authorize the connection and reach the actor.

WebSocket connections close when the actor sleeps. Clients reconnect, which wakes the actor.

HTTP

These limits affect actions that do not use .connect() and low-level HTTP requests.

NameSoft LimitHard LimitDescription
Actor start waitN/A45 secondsMaximum time a request waits for its actor to start before it fails.
Max buffered response body sizeN/A16 MiBMaximum size of a non-streaming HTTP response. Streaming responses are flow controlled and may transfer more over their lifetime.
Response start timeout60 secondsN/AMaximum time for onRequest to return response headers. Uses actionTimeout. It does not limit a response stream after the headers arrive.
Streaming response idle timeoutN/ANoneRivet does not close an otherwise healthy stream because no body chunk was produced. Other proxies and hosting platforms may impose their own idle timeouts, so SSE handlers should send periodic comment heartbeats.

Request bodies are streamed to the actor and have no fixed size limit.

Queue

NameSoft LimitHard LimitDescription
Max queue size1,000 messagesN/AMaximum number of messages in the queue before new messages are rejected. Configurable via maxQueueSize.
Max queue message size64 KiBN/AMaximum size of each individual queue message. Configurable via maxQueueMessageSize.

Schedule

NameSoft LimitHard LimitDescription
Max scheduled events1,000N/AMaximum number of pending scheduled events per actor. Configurable via maxSchedules.

Actor Storage

Each Rivet Actor has one durable volume. Its SQLite database and its KV data live in that volume.

Actor KV Storage

These limits apply to the KV API.

NameSoft LimitHard LimitDescription
Max key sizeN/A2 KiBMaximum size of a single key.
Max value sizeN/A128 KiBMaximum size of a single value.

A large batch put is split into several transactions, so it is not atomic. Keep entries that must change together in one small batch.

Actor SQLite Storage

These limits apply to the SQLite database.

NameSoft LimitHard LimitDescription
Max pages changed per transactionN/A32,768 pages (128 MiB)Maximum SQLite pages one transaction can change, at 4 KiB per page. A larger transaction fails with sqlite.transaction_too_large and is rolled back; the database stays usable.
Transaction deadline60 secondsN/ASafety backstop for db.transaction(). Configure per transaction with { timeout: milliseconds }; there is no product-level maximum.
Transaction coordinator queueN/A128 operationsMaximum admitted SQLite operations waiting behind an active coordinated transaction. Additional operations fail with sqlite.transaction_queue_full.
Max database size (remote SQL)N/A256 MiB (65,536 pages)Applies when queries run on the control plane: always on the WebAssembly runtime, and on native runtimes with sqlite.backend set to "remote".
Max value and result size (remote SQL)N/A24 MiBMaximum size of one value and of one statement’s result when queries run on the control plane.

Large commits are sent in internal chunks, but each transaction is published atomically. The limit counts raw pages changed, before compression.

If a transaction fails with sqlite.transaction_too_large, split the work into smaller transactions, for example by inserting, updating, or deleting rows in batches. VACUUM rewrites the whole database in one transaction, so it runs only while the database’s in-use pages fit under this limit; it is refused up front on larger databases. Building an index on a large table can also exceed the limit.

Actor Runtime Socket

The Beta Actor Runtime Socket negotiates its active frame limit during the handshake.

NameSoft LimitHard LimitDescription
Frame payload size32 MiBN/ADefault maximum request or response payload. Self-hosted native runtimes can configure RIVET_ACTOR_RUNTIME_SOCKET_MAX_FRAME_BYTES; oversized responses return ResponseTooLarge.

Names and Keys

NameSoft LimitHard LimitDescription
Max actor key total sizeN/A1,024 bytesMaximum total size of the serialized actor key.
Max actor name lengthN/A64 bytesMaximum length of an actor name.
Max namespace and pool name lengthN/A63 bytesMaximum length of a namespace slug or node pool name.

Timeouts

NameSoft LimitHard LimitDescription
Action timeout60 secondsN/ATimeout for RPC actions and for raw onRequest handlers to return response headers. Configurable via actionTimeout.
On before connect timeout5 secondsN/ATimeout for the onBeforeConnect hook. Configurable via onBeforeConnectTimeout.
Create vars timeout5 secondsN/ATimeout for createVars hook. Configurable via createVarsTimeout.
Create conn state timeout5 secondsN/ATimeout for createConnState hook. Configurable via createConnStateTimeout.
On connect timeout5 secondsN/ATimeout for onConnect hook. Configurable via onConnectTimeout.
On migrate timeout30 secondsN/ATimeout for onMigrate hook. Configurable via onMigrateTimeout.
Sleep grace period15 secondsN/ATotal graceful shutdown budget for both sleep and destroy. Covers onSleep/onDestroy, run handler shutdown, waitUntil, keepAwake, async raw WebSocket handlers, and connection cleanup. Configurable via sleepGracePeriod.
Sleep timeout30 secondsN/ATime of inactivity before actor hibernates. Configurable via sleepTimeout.
State save interval1 secondN/AInterval between automatic state saves. Configurable via stateSaveInterval.
Connection liveness timeout2.5 secondsN/ATime a stateful connection can miss liveness checks before RivetKit treats it as unhealthy. Configurable via connectionLivenessTimeout.
Connection liveness interval5 secondsN/AInterval between stateful connection liveness checks. Configurable via connectionLivenessInterval.

Actor Lifecycle

NameSoft LimitHard LimitDescription
Actor start thresholdN/A15 secondsMaximum time for an actor to start. A start that takes longer is stopped.
Node lost thresholdN/A40 secondsTime after a node’s connection drops before its actors are rescheduled on other nodes.

Increasing Limits

These limits are sane defaults designed to protect your application from exploits and accidental runaway bugs. If you have a use case that requires different limits, contact us to discuss your requirements.