> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/faq/error-handling/handle-429-rate-limit-errors.md).

# Handle 429 rate-limit errors

Understand Triton's rate-limit window, read the response headers, and back off and retry to clear 429 errors.

When your traffic exceeds a rate limit on a Triton endpoint, the load balancer returns `HTTP 429 Too Many Requests`. The request wasn't forwarded, so you can safely retry it once the window allows.

## The 10-second window

Triton's load balancers count requests over a rolling 10-second window. These budgets apply at the same time:

* **Total requests**: the budget for your IP across every method.
* **Per-method requests**: a separate, lower budget for each RPC method from your IP.
* **Endpoint requests**: on some tiers, a budget for your endpoint as a whole.

New connections from your IP and concurrent WebSocket connections from your IP are capped as well. A 429 means one of these limits was exceeded, and the JSON-RPC error message says which:

| Message                                                                            | Limit exceeded                                                            |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `Too many requests from your IP`                                                   | Total requests from your IP                                               |
| `Too many requests for a specific RPC call`                                        | Requests for one method from your IP                                      |
| `Too many requests on this endpoint`                                               | Requests on your endpoint as a whole                                      |
| `Connection rate limits exceeded`                                                  | New connections from your IP                                              |
| `Too many pubsub connections from your IP`                                         | Concurrent WebSocket connections                                          |
| `You've either reached your airdrop limit today or the airdrop faucet has run dry` | `requestAirdrop` calls on devnet (`Retry-After` is 86400 seconds, not 10) |

See [Rate and connection limits](/using-your-endpoint/rate-and-connection-limits.md) for how to read your endpoint's live limits.

## Read the response headers

JSON-RPC responses can carry `X-Ratelimit-*` headers, though not every endpoint returns them. Where they appear, watch them in your client to back off **before** you hit a 429:

| Header                                                                                                                                             | Meaning                                                                                                                                                                                                                                                                                                |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `X-Ratelimit-Tier`                                                                                                                                 | The rate tier applied to your requests                                                                                                                                                                                                                                                                 |
| `x-ratelimit-rps-limit` / `x-ratelimit-rps-remaining`, `x-ratelimit-endpoint-limit` / `x-ratelimit-endpoint-remaining`                             | Request budget for the current 10-second window, per IP (`rps`) and for your endpoint as a whole (`endpoint`), and how many requests are left                                                                                                                                                          |
| `X-Ratelimit-Conn-Limit` / `X-Ratelimit-Conn-Remaining`, `X-Ratelimit-ConnRate-Limit`, `X-Ratelimit-Pubsub-Limit` / `X-Ratelimit-Pubsub-Remaining` | Concurrent-connection limit and how many you have left, the new-connection rate limit, and the WebSocket (pubsub) connection limit and how many you have left. Don't rely on `X-Ratelimit-ConnRate-Remaining`: it repeats the concurrent-connection remaining value, not the connection-rate remaining |
| `X-Ratelimit-Method-Limit`                                                                                                                         | Per-method cap for this RPC                                                                                                                                                                                                                                                                            |
| `X-Ratelimit-Method-Remaining`                                                                                                                     | How many of this method you have left                                                                                                                                                                                                                                                                  |

## Backoff and retry

{% stepper %}
{% step %}

### Pause for `Retry-After`

Wait the `Retry-After` time the 429 response gives (10 seconds for the limits above; 86400 for the airdrop limit) so the window can clear. WebSocket connection-limit responses carry no `Retry-After`, so wait at least 10 seconds.
{% endstep %}

{% step %}

### Retry the same request

It didn't reach the validator, so resending is safe.
{% endstep %}

{% step %}

### Back off exponentially

If the retry also 429s, double the wait each attempt up to a cap (e.g. 30 seconds).
{% endstep %}

{% step %}

### Reset the backoff

Once a request succeeds, start again from the first wait.
{% endstep %}
{% endstepper %}

### TypeScript example

{% code title="rpcWithBackoff.ts" %}

```typescript
async function rpcWithBackoff(url: string, body: unknown, maxAttempts = 5) {
  let delay = 10_000; // start at 10s, the rate-limit window
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(url, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (res.status !== 429) return res.json();
    if (attempt === maxAttempts) {
      throw new Error(`429 after ${maxAttempts} attempts`);
    }
    const retryAfter = Number(res.headers.get("Retry-After")) * 1000 || delay;
    await new Promise((r) => setTimeout(r, retryAfter));
    delay = Math.min(delay * 2, 30_000);
  }
}
```

{% endcode %}

## Reduce 429s before they happen

* **Batch reads**: `getMultipleAccounts` instead of N parallel `getAccountInfo` calls.
* **Cache hot reads** at your application layer.
* **Move heavy reads** (program scans, signature crawls) to your backend.
* **Lower your concurrency** until the per-method headers stop ticking near zero.
* **Ask support** to raise your tier if you're consistently against the cap on legitimate traffic. Contact support by clicking the chat icon in the bottom right of your [customer dashboard](https://customers.triton.one).

## What's next

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-gauge">:gauge:</i> <strong>Rate and connection limits</strong></td><td>Per-endpoint and method rate limits, plus streaming connection caps.</td><td><a href="/using-your-endpoint/rate-and-connection-limits.md">Rate and connection limits</a></td></tr><tr><td><i class="fa-circle-question">:circle-question:</i> <strong>Common Solana errors</strong></td><td>Solana JSON-RPC error codes and how to handle each one.</td><td><a href="/solana/faq/error-handling/common-solana-errors.md">Common Solana errors</a></td></tr><tr><td><i class="fa-triangle-exclamation">:triangle-exclamation:</i> <strong>Triton RPC error codes</strong></td><td>Triton-specific error codes you might see and what they mean.</td><td><a href="/solana/faq/error-handling/triton-rpc-error-codes.md">Triton RPC error codes</a></td></tr><tr><td><i class="fa-wrench">:wrench:</i> <strong>How to troubleshoot</strong></td><td>The full debug flow when something's not working as expected.</td><td><a href="/solana/faq/error-handling.md">Error handling</a></td></tr></tbody></table>

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
