Trading bot API rate limits: 429 errors, backoff and queues

Exchange APIs limit how much traffic a bot may send. A bot that ignores those limits often fails at the worst moment: market-data polling consumes the budget, then a cancel or risk check is throttled. The fix is a central request scheduler that understands weights, reserves emergency capacity, uses streams for live data, and treats order retries differently from harmless reads.

On this page
  1. How limits are measured
  2. Build a request budget
  3. Handle 429 safely
  4. Protect order actions
  5. Monitor and test
  6. FAQ

How exchange rate limits are measured

A rate limit is a rule that caps API activity during a time window. The details are venue-specific and change over time, so never paste a number from a comparison article into production. Read the current documentation for every endpoint your bot uses. For examples of different models, compare the official Coinbase Exchange REST rate-limit documentation with Kraken's trading rate-limit documentation.

Limit modelWhat gets countedCommon surprise
Requests per windowCalls per second or minuteBursts fail even when the minute average looks low
Weighted requestsEach endpoint consumes a different number of unitsOne broad snapshot can cost many simple calls
Token bucketTokens refill over time; each call spends tokensShort bursts are allowed, then capacity disappears
Order activityNew, amended, or cancelled ordersCancel-replace loops can exhaust it rapidly
Connection/messageWebSocket connects, subscriptions, or messagesReconnect storms create their own ban risk

Scopes may be per IP address, API key, account, subaccount, trading pair, or endpoint group. Two bot processes using the same account may therefore consume one shared allowance even when each appears below its own local limit. Response headers or API payloads sometimes expose used weight and reset time; record them when available.

Build one request budget for the whole bot

Rate limiting belongs in a shared exchange gateway, not scattered sleep() calls inside strategies. A central scheduler knows the real combined load and can give safety actions priority.

PriorityExamplesPolicy near the limit
CriticalCancel, reduce-only exit, kill-switch snapshotReserved capacity; never blocked by research work
HighOrder status, positions, balance reconciliationRun promptly; coalesce duplicate requests
NormalSignal-time reads not available on a streamQueue within a freshness deadline
LowHistory downloads, dashboards, analyticsDefer or drop when capacity is tight

Subscribe once to a WebSocket feed and fan the data out internally instead of letting every strategy poll the same ticker. Cache immutable market metadata and briefly cache safe account reads when exact real-time values are not required. Batch supported queries. Add deadlines: a quote that arrives after the strategy's decision window should be discarded rather than executed late.

Libraries can help, but configuration is not a guarantee. The ccxt guide shows its built-in throttling option; your application still has to coordinate multiple processes and prioritize risk traffic.

Handle 429 with bounded exponential backoff and jitter

HTTP 429 Too Many Requests or an equivalent venue error means slow down. Honor a valid Retry-After or reset value when the venue supplies one. Otherwise, use exponential backoff capped at a sensible maximum, plus random jitter so multiple workers do not wake and collide at the same instant.

python · retry reads, not unknown writesimport random, time

def retry_read(request, attempts=5):
    for n in range(attempts):
        response = request()
        if response.status != 429:
            return response
        delay = min(8.0, 0.25 * (2 ** n))
        time.sleep(delay + random.uniform(0, delay * 0.25))
    raise RateLimitUnavailable()

Retries must be bounded. A long retry queue can become stale work that floods the venue after recovery. Apply a circuit breaker: after repeated throttles, pause noncritical traffic, mark data unhealthy, and let the kill switch block new entries if execution safety is uncertain.

Backoff is not just sleeping

The bot should reduce demand, discard obsolete work, share one cooldown across workers, and expose a degraded state. Without those controls, each sleeping task eventually returns and recreates the same traffic spike.

Order actions need idempotency, not blind retry

Read requests such as fetching a ticker are normally safe to repeat. Write requests are different. If an order submission times out, the exchange may have accepted it even though the bot saw no response. Sending the same trade again can double exposure.

  1. Assign a unique, persistent client order ID before submitting.
  2. If the result is ambiguous, mark the intent UNKNOWN and block conflicting actions.
  3. Query by client ID and inspect recent fills and open orders.
  4. Submit a replacement only after proving the original was not accepted.
  5. Reconcile resulting position and protection before strategy execution continues.

Cancels can be ambiguous too: an order may fill while the cancel is in flight. Treat “order not found” as a reason to fetch final state, not proof that nothing happened. The complete execution pattern is covered in partial fills and order reconciliation.

Monitor the budget and test exhaustion

Log endpoint, weight, scope, latency, response code, retry count, queue depth, and reported remaining allowance without logging secrets. Alert before the hard limit, not only after 429s begin. Useful dashboards show consumption by strategy so one noisy component is easy to isolate.

Test with a fake exchange adapter that returns 429s, slow responses, incomplete pages, and changing reset headers. Verify that:

Finally, keep rate-limit rules in configuration with a review date and link to the venue source. Limits can change, account tiers can differ, and a sandbox may not behave like production.

Not financial advice. This content is educational. Automated and algorithmic trading carries a real risk of financial loss. Never trade money you cannot afford to lose. Review the SEC investor.gov and CFTC resources before trading.

Frequently asked questions

What happens when a trading bot exceeds an API rate limit?

The venue commonly rejects or delays requests, often with HTTP 429 or a venue-specific error. Continued traffic can extend the throttle or trigger a temporary ban. The bot should stop nonessential calls, honor Retry-After or reset information when supplied, and retry with bounded backoff and jitter.

Should a trading bot retry every 429 error?

Only safe and necessary operations should be retried. Read requests are usually repeatable, but an order submission may have succeeded before its response was lost. Query by client order ID before retrying any ambiguous write so the bot cannot duplicate a trade.

Do WebSockets eliminate exchange API rate limits?

No. WebSockets reduce repetitive market-data polling, but connection attempts, subscriptions, messages, and private trading operations can have separate limits. Bots still need a request budget and a REST path for snapshots and reconciliation.

How can multiple strategies share one exchange API limit?

Route all calls through a central scheduler that understands endpoint weights and venue scopes. Reserve capacity for cancels, risk checks, and reconciliation; coalesce duplicate reads; cache safe responses briefly; and make research or historical downloads use a separate low-priority budget.

MB

Mustafa Bilgic

Algorithmic trading practitioner · Founder, AITradingBot.us

Mustafa builds and backtests automated trading systems and writes about them without the hype. Every tool on this site is free and runs entirely in your browser.