Skip to content

Rate limits and capacity

The backend limits below show the default configuration values. Client limits are listed separately.

The backend does not apply a per-caller rate limit. Each bidirectional stream has separate token buckets for update frames and client ping frames: 10 frames per second with a burst of 100. Pong frames do not consume either bucket. Exhaustion closes the stream with RESOURCE_EXHAUSTED. Reconnect with backoff from durable per-topic cursors.

A request above a structural limit is rejected with INVALID_ARGUMENT. An oversized publish envelope is also rejected with INVALID_ARGUMENT. A message-size rejection from the transport arrives as OUT_OF_RANGE. Reduce the batch or payload before sending it again. Query row limits are clamped to the configured maximum.

LimitDefault
Envelope bytes1 MiB
Request bytes25 MiB
Response bytes25 MiB
Distinct topics in one publish1,000
Topics in one query1,000
Rows returned by one query100 by default, 1,000 maximum
Newest-envelope topics, metadata only1,000
Newest-envelope topics, full envelopes100
Identifiers in one inbox-ID lookup250
Signatures in one smart-contract-wallet verify request100
Identity-update entries per inbox256
LimitDefault
Topics registered on one bidirectional stream100,000
Topics added by one stream update100,000
Topics removed by one stream update100,000
Topics in one static subscription10,000
Stream update frames10 per second, burst 100
Client ping frames10 per second, burst 100
Keepalive interval30 s
Concurrent HTTP/2 streams on one connection100

A stream that exhausts its token bucket receives RESOURCE_EXHAUSTED. Reconnect with backoff from your durable per-topic cursors.

The server advertises the HTTP/2 stream limit through the transport. A client that follows that limit queues new requests until an existing stream closes. Long-lived subscriptions also consume HTTP/2 streams. This is not a per-caller request quota.

The minimum name length is the backend’s handles.min_name_length. An operator can change it from 1 to 27; a change applies only to later claims.

LimitDefault
Shortest name part, the text before #, in a claim3
Longest name part27
Handle claims per inbox64
Days between two claims by one inbox7

Each claim uses one identity-update entry of the inbox. At the default of 256 entries per inbox, 192 entries stay for membership changes.

The first two values are defaults published in the backend’s [mls] configuration. An operator can change them, and clients apply the configured values locally. The metadata byte limits are fixed in the client library.

LimitValue
Members in one group250
Active installations per inbox10
Group appData bytes8,192
Group name bytes100
Group description bytes1,000
Group image URL bytes2,048

A group message is bounded by the backend’s envelope limit, which defaults to 1 MiB. The payload must be smaller because the encoded envelope also contains MLS ciphertext and framing data.

The group cap counts inboxes, not installations. The installation cap applies separately to each inbox. See Manage inboxes.