Skip to content

Rate limits

Address and IP weight limits, per-endpoint costs, batching, and how to handle 429 responses.

Updated Nov 4, 2026Builders2 min read
On this page

Rate limits protect the exchange from bursts and keep latency predictable. Limits are applied per address and per IP.

Defaults

ScopeLimit
Address weight1,200 per minute
IP weight2,400 per minute
Orders20 per second per account
Cancels100 per second per account
WebSocket messages30 per second per connection
WebSocket subscriptions200 per connection

Endpoint weights

EndpointWeight
meta2
l2Book2
allMids2
clearinghouseState2
openOrders2
userFills20
userFillsByTime20
candleSnapshot4
fundingHistory4
order (place)4
cancel2
modify3

Batching counts per action

A batched request with 10 cancels consumes 20 weight, not 2. Batch for latency, not for evading the limit.

Headers

Every response includes:

code
X-RateLimit-Limit: 1200
X-RateLimit-Remaining: 842
X-RateLimit-Reset: 1762732860

A 429 response includes Retry-After in seconds.

Handling 429

code
async function withRetry<T>(fn: () => Promise<T>, attempts = 5): Promise<T> {
  for (let attempt = 0; attempt < attempts; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (!(error instanceof RateLimitError)) throw error;
      const wait = error.retryAfter * 1000 + Math.random() * 250;
      await new Promise((resolve) => setTimeout(resolve, wait));
    }
  }
  throw new Error("Rate limit retries exhausted");
}

Designing within limits

  • Use WebSocket for live data; poll only for reconciliation.
  • Cache meta and spotMeta for at least 60 seconds.
  • Use userFillsByTime for history instead of repeatedly fetching userFills.
  • Give each strategy its own API wallet and budget.
  • Prefer cancel-all or batch cancel when re-quoting.

Was this page helpful?