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 action and lifecycle timeouts are passed to actor(...) via options:

import { actor } from "rivetkit";

const myActor = actor({
  options: {
    actionTimeout: 60_000,
    sleepTimeout: 30_000,
    sleepGracePeriod: 15_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 a message from the client. The soft limit applies to .connect() messages and to HTTP action request bodies, not to low-level WebSockets. Soft limit configurable via maxIncomingMessageSize.
Max outgoing message size1 MiB16 MiBMaximum size of a message to the client. The soft limit applies to .connect() messages and to HTTP action responses, not to low-level WebSockets. Soft limit configurable via maxOutgoingMessageSize.
Max WebSocket frame sizeN/A16 MiBMaximum size of a single WebSocket frame accepted by Rivet’s transport edge. This is not configurable by browser clients and is not negotiated during the WebSocket handshake.
WebSocket open timeoutN/A15 secondsTime allowed for Rivet to route the connection and start the actor. The onBeforeConnect hook runs after this and has its own timeout.
Keepalive ping intervalN/A30 secondsRivet pings each client WebSocket at this interval so proxies do not close idle connections. A missed pong does not close the connection.

WebSocket connections close when the actor sleeps. Clients reconnect, which wakes the actor. An actor does not sleep from inactivity while it has open connections.

HTTP

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

NameSoft LimitHard LimitDescription
Actor wake timeoutN/A45 secondsMaximum time a request waits for its actor to be routed and started before it fails. Only relevant if something is wrong with starting actors.
Max queued requests per actorN/A1,024Maximum requests waiting for one actor, mostly while it starts. Further requests fail with envoy.actor_overloaded.
Max buffered response body sizeN/A16 MiBMaximum size of a response whose body is sent in one piece, including headers. Streaming responses have no size limit and are flow controlled instead of buffered in full.

Request bodies for low-level HTTP requests are streamed to the actor and have no fixed size limit. HTTP action request bodies are limited by maxIncomingMessageSize.

Actor Storage

Each Rivet Actor has one durable volume that holds its SQLite database. There is no fixed limit on the total storage of an actor.

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.

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

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.

Names and Keys

NameSoft LimitHard LimitDescription
Max actor key total sizeN/A1,024 bytesMaximum total size of the serialized actor key string.
Max actor name lengthN/A64 bytesMaximum length of an actor name.
Max namespace and pool name lengthN/A63 bytesNamespace and pool names are DNS labels: lowercase letters, digits, and hyphens.

Timeouts

NameSoft LimitHard LimitDescription
Action timeout60 secondsN/ATimeout for RPC actions. Configurable via actionTimeout.
Raw HTTP response start timeout60 secondsN/ATime allowed for a raw onRequest handler to return its response. Configurable via actionTimeout. A streaming response has no fixed total-duration timeout after it starts.
Raw HTTP stream idle timeoutN/ANoneRivet does not close a stream for producing no chunks. Other proxies may, so send SSE heartbeats.
On before connect timeout5 secondsN/ATimeout for the onBeforeConnect hook. Configurable via onBeforeConnectTimeout.
Create vars timeout5 secondsN/ATimeout for createVars hook. Configurable via createVarsTimeout.
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 workflow 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.

Actor Lifecycle

NameSoft LimitHard LimitDescription
Actor start thresholdN/A30 secondsMaximum time for an actor to report running after its start is sent before the start is given up and retried.
Actor stop thresholdN/A30 secondsTime a node is given to stop its actors once asked. RivetKit uses it as the default shutdown.gracePeriodMs for draining the whole process; each actor’s own budget is sleepGracePeriod. A stop that goes unanswered for about 45 seconds is treated as lost.

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.

Edit this page Last updated November 10, 2026