Corvus Labs
Yellowstone gRPC

Yellowstone gRPC limits

Connection, stream, and filter limits for Corvus Yellowstone gRPC on Solana, and which gRPC status and reason each rejection carries.

Cross a limit here and you usually get a gRPC status plus a structured reason naming what you went over, so branch on the reason. One protection skips gRPC altogether: cancel streams fast enough and the connection closes with an HTTP/2 GOAWAY carrying ENHANCE_YOUR_CALM, no gRPC status and no reason field.

Most of the limits scale with your plan's RPS.

LimitValue
Concurrent connectionsceil(RPS × 5%), minimum 1, capped at 50
accounts: account keys, summed across every accounts filterRPS
accounts: owner keys, summed across every accounts filterRPS ÷ 5
accounts: data slices10
transactions: account_include / account_exclude / account_required, each summed across every transactions filterRPS each
slots filters10
blocks_meta filters10
entry filters10
Silence timeout20 seconds

Worked through: on a 500 RPS plan that's 25 connections, 500 account keys or 100 owner keys, and 500 keys in each of account_include, account_exclude and account_required. At 1,000 RPS you get 50 connections, 1,000 accounts and 200 owners.

NFT pass holders are the exception: their caps are flat numbers rather than RPS-derived ones.

LimitProElite
accounts account keys1,2002,000
accounts owner keys200200
transactions account_include / account_exclude / account_required, each1,2002,000
slots filters50100

Data slices, blocks_meta and entry filters stay at 10 either way.

Every filter figure above is a total, not a per-filter allowance. Keys are summed across every filter in the request, and that running total is charged to your account (or to your source IP, on an IP-allowlisted endpoint) across every connection you hold to that endpoint. When a filters rejection lands it's raised against the connection that sent the offending SubscribeRequest, and that request's contribution is rolled back, so your other connections keep running.

If you need a filter set larger than your plan allows, we can arrange it; ask us on Discord.

The silence timeout is armed by your writes, not the server's. If the server has sent nothing for 20 seconds while your client is still writing to the connection, the connection closes, so an application-level keepalive won't prevent it. The fix is a filter wide enough that the server always has something to send.

Limit classes

LimitWhat it controlsFailure
ConnectionsOpen gRPC channelsRESOURCE_EXHAUSTED (8), reason connection_limit
Concurrent streamsActive RPC streams on a channelRESOURCE_EXHAUSTED (8), reason stream_limit
FiltersCount and breadth of selectorsRESOURCE_EXHAUSTED (8), reason filters
Subscription updatesHow often a connection rewrites its filter configurationRESOURCE_EXHAUSTED (8), reason subscribe_rate_limit
Stream resetsHow fast a connection cancels streams (RST_STREAM)HTTP/2 GOAWAY with ENHANCE_YOUR_CALM; the connection is terminated. No gRPC status and no reason string are sent

The weighted per-method costs in Solana RPC rate limits don't apply to a stream; streams are metered by connections, streams and filters. RPS, TPS and streaming allowances stay separate.

The PPS gate (aRPC only)

The packets-per-second gate only runs on the aRPC transport (http://arpc.<region>.corvus-labs.io:20202), so nothing on port 10101 will ever see it. It arrives as PERMISSION_DENIED (7) with the detail prefix PPS limit requirement not met, never as JSON-RPC code -32100 in an HTTP error body. If you also consume aRPC, PPS closes the connection has the requirement and the way out.

Matching detail strings

Detail strings can carry extra text after the stable prefix, including a trailing support sentence pointing at discord.gg/corvus-labs. Compare on status, reason and prefix.

Handle a rejection

SymptomCauseFix
RESOURCE_EXHAUSTED, reason stream_limitToo many concurrent streams on the channelClose unused streams before opening another
RESOURCE_EXHAUSTED, reason filtersFilter count or breadth over quotaNarrow the selector; splitting it across connections does not help
RESOURCE_EXHAUSTED, reason subscribe_rate_limitFilter configuration rewritten too oftenStop rewriting the request; back off, then send one complete configuration
HTTP/2 GOAWAY, ENHANCE_YOUR_CALMToo many stream cancellations in a short windowStop opening and cancelling streams; the connection is terminated, so reopen once
RESOURCE_EXHAUSTED, reason rate_limitGeneral allowance exhaustedReduce load, then retry
PERMISSION_DENIED, reason permission_deniedResource does not include this productCheck access; reconnecting cannot fix it
INVALID_ARGUMENT (3), message naming from_slotThe replay request breaks its contract: wrong commitment, a blocks filter, or a slot older than the retained windowSee replay on reconnect
FAILED_PRECONDITION (9), message beginning from_slot replayReplay wasn't available on the node that took this connectionReconnect and retry, or re-subscribe without from_slot and backfill through JSON-RPC
INVALID_ARGUMENT (3)Malformed request or filterFix the request; do not retry unchanged
UNAUTHENTICATED (16)Wrong x-token or unregistered egress IPSee Access & authentication

Gateway & streaming errors is the full status and reason reference, and Pricing lists the preset capacities.

On this page