Solana RPC rate limits
How Corvus meters the Solana JSON-RPC endpoint: weighted method costs, the getMultipleAccounts formula, scan concurrency, and TPS.
We meter the JSON-RPC endpoint on three separate axes, and they don't trade against each other.
| Axis | What it covers | Rejection |
|---|---|---|
| RPS units | All reads, charged at a weighted cost per method | 429 · -32001 · RPS limit exceeded |
| TPS | sendTransaction only | 429 · -32005 · Transaction rate limit exceeded |
| Scan concurrency | How many of six specific methods are in flight at once | 429 · -32005 · Scan request timed out waiting for concurrency slot |
You pick your RPS and TPS when you rent capacity in the dashboard. Everything below applies to the standard regional JSON-RPC endpoints. Connections, gRPC streams and filter quotas are counted separately; Yellowstone gRPC limits and aRPC limits cover the streaming side.
Method weights
| Method | RPS units |
|---|---|
| Most methods | 1 |
getAccountInfo, getTokenAccountBalance | 2 |
getTokenAccountsByOwner, getTokenAccountsByDelegate, getTokenLargestAccounts, getTransaction | 10 |
getProgramAccounts | 30 |
sendTransaction | 0; consumes TPS, not RPS |
Every item in a JSON-RPC batch is weighed on its own.
getMultipleAccounts
getMultipleAccounts is charged by how many accounts you ask for, and there are two rates:
| Who | Cost | 100 accounts | 500 accounts (the cap) |
|---|---|---|---|
| NFT pass holders, on any plan | ceil(accounts / 20) | 5 | 25 |
| Everyone else, below 800 plan RPS | 2 units per account | 200 | 1,000 |
| Everyone else, from 800 plan RPS | ceil(accounts / 20) | 5 | 25 |
You're charged for every account you ask for, whether or not it exists. One call can request at most 500 accounts, and that 500 is counted across a whole batch, so several getMultipleAccounts calls in one body share it.
The rate difference changes how you should read the method:
- At the per-account rate there is no batching discount: 100 accounts cost 200 units through
getMultipleAccountsand 100 × 2 = 200 throughgetAccountInfo. A 500-account call costs 1,000 units, more than a Starter or Standard plan's entire per-second allowance, so split wide reads or size up. - At
ceil(accounts / 20)the discount is real: the same 100 accounts cost 5 units againstgetAccountInfo's 200, and the 500-account cap tops out at 25.
Batch limits
| Limit | Value |
|---|---|
| Request body | 16 MiB |
| Response body | 16 MiB |
| Body read timeout | 30 seconds |
getMultipleAccounts accounts, counted across the whole batch | 500 |
Exceed the body limit, or upload slowly enough to run past the read timeout, and the whole batch fails rather than the offending item.
Scan concurrency
Six methods count as scans. They share a concurrency pool that sits on top of their RPS cost rather than replacing it:
| Concurrent scans, your account | 3 |
| Concurrent scans, all accounts | 20 |
| Wait for a slot before rejection | 5 seconds |
| Scan method | RPS units |
|---|---|
getProgramAccounts | 30 |
getTokenAccountsByOwner | 10 |
getTokenAccountsByDelegate | 10 |
getTokenLargestAccounts | 10 |
getLargestAccounts | 1 |
getSupply | 1 |
getLargestAccounts and getSupply look cheap but are scans
Both cost a single RPS unit, so they sail through RPS budgeting and traffic shaping without registering. They still take a slot in the same pool as getProgramAccounts. That's how a health check polling getSupply in parallel ends up starving your real scan work.
Scan request timed out waiting for concurrency slot
HTTP 429
code -32005
message Scan request timed out waiting for concurrency slotFrom the outside this looks like 429s on scan methods while your RPS usage sits nowhere near the allowance, often on the cheap methods first. Queue the six scan methods separately from ordinary reads; three in flight is the number to design against.
Rate limit responses
The two -32005 conditions want opposite fixes, so branch on the message prefix with startsWith. Messages sometimes carry a trailing support sentence, and equality will miss it.
If you shape traffic client-side, charge the real weights. A token bucket that counts one unit per request lets through 30× too much getProgramAccounts and 2× too much getAccountInfo.
The full error contract, including the gRPC statuses the streaming interfaces use, is in Gateway & streaming errors.
Yellowstone gRPC limits
Connection, stream, and filter limits for Corvus Yellowstone gRPC on Solana, and which gRPC status and reason each rejection carries.
Gateway & streaming errors
Corvus Solana JSON-RPC and gRPC error reference: exact codes, message prefixes, gRPC reasons, and which failures are retryable.