Skip to main content
RPC operator referenceHTTPS · JSON-RPC 2.0

Rate limits

Rate limiting is a token bucket per account. This page explains how it refills, how batches count, and how to handle a 429 correctly.

How the limiter works

The bucket is per account, not per API key, creating more keys does not add throughput. Every key on your account draws from the same bucket, across all chains combined.

An advanced API key policy can add a lower key-wide sustained ceiling, and a verified JWT can add a lower per-token ceiling. The gateway checks every applicable bucket atomically. These delegated ceilings can only reduce throughput and never multiply the parent account limit. Key and token burst capacity is the smaller of the parent burst or five times the sustained method rate. A per-token bucket is identified by the API key ID plus the SHA-256 digest of the byte-exact JWS signing input: base64url(protected header).base64url(payload). This is neither the decoded claims nor the full compact JWT. Excluding the signature prevents equivalent ES256 high-S and low-S signatures from creating separate buckets. See API key security.

The bucket refills at your plan's sustained rate and holds at most the burst capacity in the live catalog. A full bucket lets you send that many method calls after an idle period, whether separately or in batches, then sustain the listed rate. An HTTP request gets a 429 when its methods need more tokens than the bucket currently holds.

Limits by plan

PlanSustainedBurst capacity
Free2 RPC method calls/s10 calls
Builder120 RPC method calls/s600 calls
Solid600 RPC method calls/s3,000 calls
Rocksolid6,000 RPC method calls/s30,000 calls
EnterpriseCustomCustom

How batches count

A batch needs one token per method call, all at once. A batch of 100 method calls needs 100 tokens available at that moment, if the bucket holds fewer, the whole batch gets 429, not a partial result. Keep batch sizes below your burst capacity. Batching requires an API key: the keyless public endpoints accept one JSON-RPC call per HTTP request.

The 429 response

A rate-limited request returns HTTP 429 with how many tokens it needed and how many were available:

Request example
{
  "error": "Rate limit exceeded",
  "requiredTokens": 1,
  "availableTokens": 0
}

A recoverable 429 also includes the wait time:

Request example
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 120
X-RateLimit-Burst: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 5

Rate-limited method calls are never billed or counted toward quota.

Response headers

Authenticated responses expose the state of both account-wide limits. Values are snapshots taken while the request is handled.

The example below uses the current Builder catalog limits with one response unit consumed.

Request example
X-RateLimit-Limit: 120
X-RateLimit-Burst: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 1
X-Quota-Limit: 10000000
X-Quota-Used: 1
X-Quota-Remaining: 9999999
X-Quota-Reset: 3600
X-Quota-Window: month
HeaderMeaning
X-RateLimit-LimitSustained token refill rate per second
X-RateLimit-BurstMaximum tokens the bucket can hold
X-RateLimit-RemainingWhole tokens available after this request
X-RateLimit-ResetSeconds until the bucket is full if traffic stops
X-Quota-LimitIncluded response units in the active quota window
X-Quota-UsedBillable response units used in the active window
X-Quota-RemainingIncluded response units left, clamped to zero during overage
X-Quota-ResetSeconds until the daily or monthly quota resets
X-Quota-Windowday or month, as listed for the active plan

During a rate-limit server outage, unrestricted legacy keys keep the existing per-pod fallback. A configured key or token with a hard delegated method-rate ceiling returns HTTP 503 when that ceiling cannot be enforced globally. The gateway never silently widens a configured security policy.

Handling 429s

When Retry-After is present, wait at least that many seconds, then retry with exponential backoff plus jitter. If a batch needs more tokens than X-RateLimit-Burst, the gateway omits Retry-After because waiting cannot make it fit, split the batch. A 402 is a quota problem, not a rate problem, see pricing and overage billing.

viem's http transport retries failed requests by default, tune retryCount and retryDelay for your traffic:

Request example
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";

const client = createPublicClient({
  chain: mainnet,
  transport: http("https://rpc.solidrpc.io/YOUR_API_KEY/evm/1", {
    retryCount: 5,
    retryDelay: 200,
  }),
});

ethers v6 does not auto-retry 429s, wrap calls in your own backoff if you use ethers.

If you see sustained 429s at your expected traffic level, you need the next plan, backoff only smooths spikes, it does not create throughput.