Arc Mainnet is now live on Chainstack! Deploy reliable nodes for stablecoin finance today.    Start building
  • Agents
  • Pricing

How to fix RPC rate limit errors (429) in 2026

Created Sep 30, 2026 Updated Sep 30, 2026
Rpc Errors 1 logo

TL;DR: The fastest way to make an RPC rate limit worse is to retry the failed call immediately. Your retry loop adds requests to the exact second that is already full. Read what the 429 is actually telling you (requests per second, a method-specific cap, or a block range), slow the client down with backoff and a throttle, send fewer requests, and only then pay for a higher limit.

An RPC rate limit error looks simple: your app sends too many requests, the endpoint answers with HTTP 429 Too Many Requests, and something downstream breaks. The fix is less obvious, because at least three different limits produce the same symptom, and each one needs a different change.

This guide walks through how to tell them apart, how to fix your call pattern first, and when raising the limit is the right move. Limits quoted below are Chainstack’s published figures; the diagnosis and the client-side fixes apply to any provider.

What an RPC rate limit error actually means

On Chainstack, a 429 means you hit an RPS or connection limit. The response tells you that you were too fast, not that the request was wrong, so the same request will normally succeed a moment later if you slow down.

On a Chainstack node, an RPS limit comes back as HTTP 429 with a JSON-RPC error in the body. This is a real response from a Sui Mainnet Global Node on the Developer plan, captured on September 30, 2026 after a burst of parallel requests:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32005,
    "message": "You've exceeded the RPS limit available on the current plan. Learn more how to increase the limit, visit https://docs.chainstack.com/docs/pricing-introduction#rate-limits",
    "data": { "try_again_in": "292.270667ms" }
  }
}

Code -32005 is what EIP-1474 lists as “Limit exceeded”, so other providers use it too. Notice what is missing: the response had no Retry-After header. The wait hint is in error.data.try_again_in. On Chainstack, a Solana getProgramAccounts request over its limit also returns 429 with -32005. Treat all of these the same way.

Four situations are easy to misread:

  • A connection limit, not a request rate. Many workers or WebSocket clients opening connections at once can trigger a 429 on their own. The Throughput guidelines list the limits that apply to your node.
  • A public endpoint. A free public endpoint is shared with everyone using it, its limits can change without notice, and its operators say it is not meant for production. Solana’s public endpoint, for example, allows 100 requests per 10 seconds per IP. The first fix is a private endpoint of your own.
  • A 429 that is not real. Open the node’s Metrics in the Chainstack console (click your project, your network, then the node name) and look at the Response codes chart. If your debug logs show 429s but that chart does not, the limit is not being hit on the endpoint. Something between your client and the endpoint is producing them. Older versions of the Solana Python SDK, for example, return 429-shaped errors that do not correspond to real rate-limit hits.
  • A different error that looks like throttling. A Solana account scan that runs too long or waits too long for a free slot returns -32012, not a 429. An eth_getLogs call over too many blocks fails on the range, not on the request rate.

The four limits behind “rate limit exceeded”

LimitExample on ChainstackWhat you see
Requests per second (plan)Developer 25 RPS, Growth 250, Pro 400, Business 600, Enterprise unlimited429 when total traffic to the endpoint passes the cap
Protocol-specific RPSSolana Mainnet: Developer 5 RPS, Growth 50 RPS429 at a lower rate than the plan table suggests
Method-specific RPSSolana getBlock 400 RPS, getTokenAccountsByOwner 150 RPS, getProgramAccounts tiered by program size429 on one method while the rest of your traffic is fine
Block rangeeth_getLogs: 100 blocks on Developer, 10,000 on Growth and aboveAn error on wide ranges, regardless of request rate

The practical consequence: the total request count can be far below your plan’s RPS and you can still hit a limit, because one heavy method or one wide range is what tripped it.

How to fix RPC rate limit errors, step by step

Work through the steps in order: the first ones cost nothing, and the last one costs money.

Step 1: find out which limit you are hitting

Change nothing in the code until you know which row of that table you are in.

Decision flow for an RPC rate limit error: check whether node Metrics show the 429s, then whether all methods, one method or wide eth_getLogs ranges fail, which points to a fake limit, the plan or protocol RPS, a method cap, or the block range
  1. Open the node’s Metrics (click your project, your network, then the node name). Response codes shows how many 429s the node returned, and Method calls shows which methods the traffic comes from. Both charts cover HTTP requests only, for 1 hour to 7 days. Compare the 429 count with your own logs.
  2. Log the method name with every failed call. If most 429s belong to one method, look at that method’s limit, not the plan’s.
  3. Look at timing. Errors clustered at process start point to a startup burst, such as a backfill. Errors spread across the hour point to steady load above your cap.
  4. Check the limit your node is running under. The node page in the console shows a banner such as “This node is currently running under the limit of 25 requests per second” on the Developer plan.
  5. Look for a wait hint in the 429 response. On Chainstack it is error.data.try_again_in in the body, and other providers may send a Retry-After header. Either is the shortest wait you should use.

This is what that looks like on a real node. After two bursts of parallel requests against a Developer-plan node, the Requests made chart shows the spike, Method calls shows the one method that was sent, and Response codes shows that a third of the requests came back as 429:

Metrics section of a Chainstack node page after a burst of parallel requests: 311 total requests, 104 invalid, a spike on the Requests made chart, one method in Method calls, and a Response codes pie chart with 200 at 66.56% and 429 at 33.44%

To find your real ceiling before production traffic does, you can run a load test against the endpoint with Chainstack’s open-source chainbench and watch the rate at which 429s begin.

Step 2: stop retrying blindly

A tight retry loop turns one rejected request into a stream of rejected requests. Wait at least as long as the response says (error.data.try_again_in on Chainstack, or Retry-After if the provider sends it), fall back to exponential backoff when there is no hint, and add jitter so parallel workers do not retry in lockstep.

async function rpc(url, body, maxRetries = 5) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(url, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (res.status !== 429 && res.status < 500) return res.json();
    const hint = parseFloat((await res.json().catch(() => null))?.error?.data?.try_again_in);
    const wait = hint || parseFloat(res.headers.get("retry-after")) * 1000 || 2 ** attempt * 1000;
    await new Promise((r) => setTimeout(r, wait + Math.random() * 250));
  }
  throw new Error("Rate limited or unavailable after retries");
}

Retry only temporary failures: a 429 or a 5xx response. A 4xx that says the request itself is wrong will fail the same way every time.

Step 3: throttle before you hit the limit

Backoff reacts after the limit trips. A client-side throttle stops it from tripping. Cap the request rate and the number of parallel calls a little below the limit you found in step 1, so a burst has headroom.

  • Node.js: bottleneck or p-throttle
  • Python: the ratelimit decorator, or asyncio.Semaphore with asyncio.sleep
  • Go: golang.org/x/time/rate

Pair the throttle with a small concurrency cap and the backoff above. Together they handle both routine bursts and the occasional spike.

Step 4: send fewer requests

When throttling alone is not enough, the call pattern is usually the real problem.

  • Batch. Combine several JSON-RPC calls into one HTTP request when the protocol supports batch arrays.
  • Read logs in ranges. For catch-up reads, one eth_getLogs call over a range beats a loop of eth_getBlockByNumber calls.
  • Subscribe instead of polling. Use eth_subscribe over WebSocket for new blocks and events, rather than asking every few hundred milliseconds. See HTTP vs WebSocket for EVM nodes.
  • Cache what does not change. A finalized block, a mined transaction and its receipt never change, so read them once.
  • Deduplicate. If ten components ask for the same block at the same moment, send one request and share the answer.
  • Check your library. In viem, the http transport retries three times by default with exponential backoff (retryCount, retryDelay) and can group calls with batch: true. In ethers v6, staticNetwork stops the provider from asking for the chain ID on every request, which saves calls if you know the network will not change.

Step 5: respect method-specific limits

Some limits are set per method, so the fix is in how you call it.

eth_getLogs. Stay inside your plan’s block range and paginate anything wider, filtering by contract address and topics to keep responses small. The Chainstack guide to eth_getLogs limitations shows the pagination loop.

Solana getProgramAccounts. On Solana RPC, the rate limit depends on the size of the program you query, and requests with filters get a higher limit than requests without. A filtered request to a program with 1M or more accounts is limited to 3 requests per 20 seconds. Add dataSize or memcmp filters, and expect a -32012 if a scan runs past its time or memory limit. If the message says the scan was abandoned while waiting for a slot, it never ran, so retry it with backoff.

Step 6: raise the ceiling when the pattern is already lean

If sustained traffic really is above your cap after steps 2 to 5, add capacity:

  • Upgrade the plan. Each plan step raises the RPS cap, as in the table above.
  • Add Unlimited Node to an endpoint. It converts an existing node to a flat monthly fee with an RPS tier of 25, 100, 250, 500 or 1000. It is available from the Growth plan, uses none of your plan quota, and has no overage charges. If you go over the tier, you get a rate-exceeded message rather than a bill.
  • Move to a Dedicated Node. You pay for the resources the node consumes instead of per request, and block-range limits can be customized on request.
  • Ask for custom limits. Enterprise customers can request a custom RPS, including for method-specific caps such as Solana getProgramAccounts.

Spreading traffic across several endpoints with fail-over helps availability, but it does not raise a per-endpoint cap. Measure the limit first, then decide.

Troubleshooting common rate limit errors

SymptomLikely causeFix
429s in your logs, none on the Metrics pageSomething before the endpoint is generating them, such as an old SDKUpdate the client library and check any proxy in front of the endpoint
429s only for a few seconds at startupA backfill or cache warm-up burstAdd a throttle and ramp up gradually
429s on one method onlyA method-specific capRead that method’s limit, then batch, filter or cache
Steady 429s under normal loadSustained traffic above the plan’s RPSCut request volume first, then raise the tier
eth_getLogs fails on wide rangesBlock range above your plan’s capPaginate into smaller ranges and add address and topic filters
-32012 on a Solana scanScan exceeded its time or memory limit, or waited too long for a slotNarrow the query with dataSize or memcmp filters; retry an abandoned scan with backoff

Conclusion

Do the fixes in this order: identify which of the four limits you hit, back off and throttle the client, cut the requests you do not need, and only then buy capacity. That order is cheapest, because by the time you upgrade you know how many requests per second you really need.

Frequently asked questions

What does HTTP 429 mean on an RPC endpoint?

It means your client exceeded a rate limit: too many requests per second or too many connections. The request itself was fine, so it should succeed if you wait and retry.

How do I fix ‘rate limit exceeded’ on an Ethereum RPC endpoint?

First find which limit you hit: total requests per second, a method-specific cap, or a block range on eth_getLogs. Then add retry with backoff and jitter, throttle the client, batch or cache calls, and raise the limit if traffic is still above it.

What does RPC error -32005 ‘limit exceeded’ mean?

-32005 is the JSON-RPC code that EIP-1474 lists as ‘Limit exceeded’. On Chainstack, an RPS-limit response is HTTP 429 with code -32005 and a try_again_in hint in error.data. Handle it like any 429: wait, back off and lower your request rate.

How many requests per second do I get on Chainstack?

Global Nodes are capped at 25 RPS on Developer, 250 on Growth, 400 on Pro and 600 on Business, and Enterprise has no cap. Some protocols and methods have lower limits, such as Solana Mainnet at 5 RPS on Developer and 50 on Growth.

Should I retry a 429 immediately?

No. Wait at least the hint in the response: error.data.try_again_in on Chainstack, or the Retry-After header if the provider sends one. Without a hint, use exponential backoff with a little jitter. Immediate retries add load to the second that is already over the limit.

Why do I see 429 errors in my logs but not in the Chainstack Metrics page?

Then the limit is probably not being hit on the endpoint. Something between your client and the endpoint is producing 429-shaped errors, for example an outdated SDK version or a proxy. Update the client and check what sits in front of the endpoint.

What is the eth_getLogs block range limit on Chainstack?

100 blocks per request on the Developer plan and 10,000 on Growth, Pro, Business and Enterprise. Paginate wider queries. Dedicated Nodes support custom ranges on request.

Why does my public RPC endpoint rate limit me?

A public endpoint is shared by everyone who uses it, so its limits are low and can change without notice. Solana’s public endpoint, for example, allows 100 requests per 10 seconds per IP and is not intended for production. Switch to a private endpoint with its own limits, then apply the steps in this guide.

Additional resources

SHARE THIS ARTICLE
Wallet Api 530x281 logo

Best crypto wallet APIs for developers in 2026

Compare the best crypto wallet APIs for developers in 2026: portfolio data, DeFi positions, wallet intelligence, and the RPC infrastructure layer beneath them all.

T9c0d9l8p U0a2lha30nl 07cf70c046c6 512 150x150 logo
Alex Usachev
Jun 5
Customer Stories

Saakuru Labs

Saakuru Labs seamlessly transitions businesses from Web2 to Web3 with a 4X infrastructure ROI using Chainstack Global Node.

Hypernative

Hypernative reinforces Web3 security with resilient Chainstack infrastructure, optimizing asset protection and efficiency.

IguVerse

Balancing the heavy network load of breakneck social gaming interactions on-chain with an adaptive BNB setup.