> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Helius Rate Limits

> Complete guide to Helius rate limits across all plans and products.

## What are rate limits?

Rate limits control how many requests you can make per second. When rate limits are exceeded, you'll receive an HTTP 429 response. For guidance on what to do when you hit a 429 or other transient failure, see [Retries and error handling](#retries-and-error-handling) below.

## Standard Rate Limits

Your plan has two standard rate limit groups: one for RPC requests, and one for DAS API requests. Here are the base rate limits for each Helius plan:

<table>
  <thead align="left">
    <tr>
      <th width="200">Plan</th>
      <th width="260">RPC Rate Limit</th>
      <th width="260">DAS & Enhanced APIs</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><strong>Free</strong></td>
      <td>10 requests/s</td>
      <td>2 requests/s</td>
    </tr>

    <tr>
      <td><strong>Developer</strong></td>
      <td>50 requests/s</td>
      <td>10 requests/s</td>
    </tr>

    <tr>
      <td><strong>Business</strong></td>
      <td>200 requests/s</td>
      <td>50 requests/s</td>
    </tr>

    <tr>
      <td><strong>Professional</strong></td>
      <td>500 requests/s</td>
      <td>100 requests/s</td>
    </tr>

    <tr>
      <td><strong>Enterprise</strong></td>
      <td>Custom</td>
      <td>Custom</td>
    </tr>
  </tbody>
</table>

### Increase Rate Limits

Teams on Professional plans can purchase an extra 100 RPS for \$100/month.

If you need custom rate limits ahead of launches, [contact our sales team](https://www.helius.dev/contact). If you are on Developer or Business tier, please upgrade your plan to increase your rate limits.

## Special Rate Limits

Some endpoints and specialized Helius products have special rate limits due to their computational requirements.

### Sending Transactions

<table>
  <thead align="left">
    <tr>
      <th width="200">Endpoint</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>Sender</code></td>
      <td>50/sec</td>
      <td>50/sec</td>
      <td>50/sec</td>
      <td>50/sec</td>
    </tr>

    <tr>
      <td><code>sendTransaction</code></td>
      <td>1/sec</td>
      <td>5/sec</td>
      <td>50/sec</td>
      <td>100/sec</td>
    </tr>

    <tr>
      <td><code>sendBundle</code></td>
      <td>—</td>
      <td>—</td>
      <td>5/sec</td>
      <td>5/sec</td>
    </tr>

    <tr>
      <td><code>simulateBundle</code></td>
      <td>10/sec</td>
      <td>50/sec</td>
      <td>200/sec</td>
      <td>500/sec</td>
    </tr>
  </tbody>
</table>

If you are on a Professional plan and need to increase your `sendTransaction` rate limits, [contact our sales team](https://www.helius.dev/contact).

Professional plan users can also [request](https://www.helius.dev/contact) rate limit increases and custom tip arrangements for Sender to support higher-throughput trading apps.

### Complex RPC Calls

<table>
  <thead align="left">
    <tr>
      <th width="200">Endpoint</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>getProgramAccounts</code></td>
      <td>5/sec</td>
      <td>25/sec</td>
      <td>50/sec</td>
      <td>75/sec</td>
    </tr>
  </tbody>
</table>

### Historical Data

When making batch requests for historical data methods, the following limits apply:

<table>
  <thead align="left">
    <tr>
      <th style={{width: '300px'}}>Method</th>
      <th style={{width: '300px'}}>Max Batch Size</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>getTransaction</code></td>
      <td>100 items per request</td>
    </tr>

    <tr>
      <td><code>getTransactionsForAddress</code></td>
      <td>No batch requests allowed</td>
    </tr>

    <tr>
      <td><code>getTransfersByAddress</code></td>
      <td>No batch requests allowed</td>
    </tr>

    <tr>
      <td>All other historical methods</td>
      <td>10 items per request</td>
    </tr>
  </tbody>
</table>

<Warning>
  Exceeding batch limits will result in an error response. For `getTransactionsForAddress` and `getTransfersByAddress`, each address must be queried in a separate request.
</Warning>

### LaserStream

<table>
  <thead align="left">
    <tr>
      <th width="200">Resource</th>
      <th width="50">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="150">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Networks</td>
      <td>—</td>
      <td>Devnet</td>
      <td>Devnet, Mainnet</td>
      <td>Devnet, Mainnet</td>
    </tr>

    <tr>
      <td>Max Pubkeys</td>
      <td>—</td>
      <td>10M</td>
      <td>10M</td>
      <td>10M</td>
    </tr>

    <tr>
      <td>Active Connections</td>
      <td>—</td>
      <td>—</td>
      <td>10</td>
      <td>100</td>
    </tr>
  </tbody>
</table>

### Wallet API

The [Wallet API](/api-reference/wallet-api) follows the same rate limits as DAS & Enhanced APIs. All endpoints share these limits:

<table>
  <thead align="left">
    <tr>
      <th width="200">Endpoint</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>All Wallet API Endpoints</td>
      <td>2/sec</td>
      <td>10/sec</td>
      <td>50/sec</td>
      <td>100/sec</td>
    </tr>
  </tbody>
</table>

This includes identity lookups, balances, history, transfers, and funding source endpoints. Learn more in our [Wallet API documentation](/wallet-api/overview).

### LaserStream WebSocket

<table>
  <thead align="left">
    <tr>
      <th width="200">Resource</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Concurrent Connections</td>
      <td>5</td>
      <td>150</td>
      <td>250</td>
      <td>1,000</td>
    </tr>

    <tr>
      <td>Subscriptions per Connection</td>
      <td>1,000</td>
      <td>1,000</td>
      <td>1,000</td>
      <td>1,000</td>
    </tr>

    <tr>
      <td>WebSocket Types</td>
      <td>Standard</td>
      <td>Standard, Enhanced</td>
      <td>Standard, Enhanced</td>
      <td>Standard, Enhanced</td>
    </tr>
  </tbody>
</table>

### Webhooks

<table>
  <thead align="left">
    <tr>
      <th width="200">Resource</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Max Webhooks</td>
      <td>5</td>
      <td>50</td>
      <td>50</td>
      <td>50</td>
    </tr>

    <tr>
      <td>Addresses per Webhook</td>
      <td>100k</td>
      <td>100k</td>
      <td>100k</td>
      <td>100k</td>
    </tr>
  </tbody>
</table>

### ZK Compression

<table>
  <thead align="left">
    <tr>
      <th width="200">Service</th>
      <th width="100">Free</th>
      <th width="100">Developer</th>
      <th width="100">Business</th>
      <th width="100">Professional</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>Photon APIs</td>
      <td>2/sec</td>
      <td>10/sec</td>
      <td>50/sec</td>
      <td>100/sec</td>
    </tr>

    <tr>
      <td><code>getValidityProof</code></td>
      <td>1/sec</td>
      <td>5/sec</td>
      <td>10/sec</td>
      <td>20/sec</td>
    </tr>
  </tbody>
</table>

## Retries and error handling

When your application receives a `429 Too Many Requests`, `503 Service Unavailable`, or transient `5xx` response, wait a moment and retry — don't retry immediately. Immediate retries pile up requests and make rate-limit recovery slower, not faster.

### Recommended strategy

* Wait about **1 second** before the first retry.
* **Double the wait** each time you retry, up to a maximum of **30 seconds**.
* Add a small random variation of **±25%** to each wait so multiple applications don't all retry at the same instant.
* Give up after **5 attempts** and return the error to the code that called you.

### Which errors to retry

| Status                     | Retry? | Reason                                                |
| -------------------------- | ------ | ----------------------------------------------------- |
| `400`, `401`, `403`, `404` | No     | Client errors — retrying will not change the outcome. |
| `408`                      | Yes    | Request timeout.                                      |
| `409`                      | No     | Conflict — resolve at the caller.                     |
| `422`                      | No     | Validation error.                                     |
| `429`                      | Yes    | Rate limit exceeded — wait and retry with backoff.    |
| `500`, `502`               | Yes    | Transient server error.                               |
| `503`                      | Yes    | Service unavailable — wait and retry with backoff.    |
| `504`                      | Yes    | Gateway timeout.                                      |
| Network error              | Yes    | Connection reset, DNS failure, or socket timeout.     |

### Example

<CodeGroup>
  ```ts TypeScript theme={"system"}
  const RETRYABLE = new Set([408, 429, 500, 502, 503, 504]);

  export async function callWithRetry<T>(
    request: () => Promise<Response>,
    maxAttempts = 5,
  ): Promise<T> {
    let delay = 1000;
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      const res = await request();
      if (res.ok) return (await res.json()) as T;

      if (!RETRYABLE.has(res.status) || attempt === maxAttempts) {
        throw new Error(`${res.status} after ${attempt} attempt(s): ${await res.text()}`);
      }

      const jitterMs = delay * (0.75 + Math.random() * 0.5);
      await new Promise((r) => setTimeout(r, jitterMs));
      delay = Math.min(delay * 2, 30_000);
    }
    throw new Error("unreachable");
  }
  ```

  ```python Python theme={"system"}
  import random
  import time

  RETRYABLE = {408, 429, 500, 502, 503, 504}

  def call_with_retry(request, max_attempts: int = 5):
      delay = 1.0
      for attempt in range(1, max_attempts + 1):
          response = request()
          if response.ok:
              return response.json()

          if response.status_code not in RETRYABLE or attempt == max_attempts:
              response.raise_for_status()

          time.sleep(delay * random.uniform(0.75, 1.25))
          delay = min(delay * 2, 30.0)
  ```

  ```bash Shell theme={"system"}
  call_with_retry() {
    local attempt=1 delay=1 body status
    while [ "$attempt" -le 5 ]; do
      response=$(curl -sS -w "\n%{http_code}" "$@")
      body=$(printf '%s\n' "$response" | sed '$d')
      status=$(printf '%s\n' "$response" | tail -n1)
      case "$status" in
        2*) printf '%s\n' "$body"; return 0 ;;
        408|429|500|502|503|504) ;;  # fall through and retry
        *) printf '%s\n' "$body" >&2; return 1 ;;
      esac
      # ~delay seconds with 25% jitter
      sleep "$(awk -v d="$delay" 'BEGIN { srand(); print d * (0.75 + rand() * 0.5) }')"
      delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))
      attempt=$(( attempt + 1 ))
    done
    return 1
  }
  ```
</CodeGroup>

### Error response shape

All Helius APIs return a structured JSON body on error. JSON-RPC endpoints (Solana RPC, DAS, Sender, Priority Fee, ZK Compression) return the standard JSON-RPC 2.0 envelope:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "error": { "code": -32005, "message": "Too many requests" },
  "id": "1"
}
```

REST endpoints (Wallet API, Admin API) return:

```json theme={"system"}
{
  "error": "RATE_LIMIT_EXCEEDED",
  "code": 429,
  "details": "Too many requests. Retry after 2 seconds."
}
```

See [Common error codes](/api-reference/common-error-codes) for the full list of error codes and what each one means.
