Learn / Exchange APIs

WebSocket vs REST for trading

Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs before acting on a number.

Use WebSocket to know what is happening. Use REST to make something happen.

That division gets you most of the way, and the failure it prevents is specific: polling REST for data that could be streamed spends a budget you will need for order management.

What each is actually for

WebSocket is a persistent connection the venue pushes updates down. Well-suited to prices and order books, your own order and fill updates, and position and balance changes. You do not ask; you are told.

REST is request-response. Well-suited to placing, cancelling and amending orders, one-off queries, reconciliation, and anything where you need a definite answer to a definite question right now.

The dividing line is not latency — it is whether you are observing a stream of changes or performing a discrete action.

Why polling is more expensive than it looks

On Binance, REST is metered by request weight, not request count. Different endpoints cost different amounts, exceeding the budget returns -1003 TOO_MANY_REQUESTS, and severe or repeated violations escalate to an IP ban signalled by HTTP 418.

A loop polling prices every second consumes weight continuously for information a stream would deliver free of REST budget. The consequence is not just inefficiency:

The budget you burn on polling is the budget you need to cancel.

That is the version of this problem that costs money. Being rate limited while trying to exit a position is meaningfully worse than being rate limited while trying to look at one. Whatever your architecture, some headroom should be unavailable to routine data refresh.

Rate limits are structured differently per venue and none of them should be assumed from another:

  • Binance — weight-based, -1003, escalating to 418.
  • Bybit10006 for account-level and 10018 for IP-level under UTA, plus 20003 on WebSocket for “too frequent requests under the same session”. The account/IP split matters: one is fixed by slowing down, the other by not sharing an address.
  • Hyperliquid — 1200 weighted REST requests per minute per IP, max 10 WebSocket connections, 30 new connections per minute, 1000 subscriptions, 2000 messages per minute. Plus an address-based allowance earned by volume: one request per 1 USDC traded cumulatively, with an initial buffer of 10,000. A new account’s budget is small regardless of how generous the IP limit looks.
  • IBKR Client Portal Web API — 10 requests per second per authenticated username.

Note that WebSocket has its own limits — connection counts, subscription counts, message rates. Streaming is not free, it is metered differently.

Where WebSocket misleads people

A stream is not a source of truth. It is a sequence of updates. Miss one during a reconnect and your state diverges silently, which is worse than an error because nothing reports it.

Reconnects are normal. Design for them: resubscribe, and reconcile via REST afterwards rather than assuming you picked up where you left off. This is the single most common bug in stream-based trading clients.

Sequence numbers exist for a reason. Where a venue provides them, check for gaps. CCXT models this failure explicitly — ChecksumError is a subclass of InvalidNonce under NetworkError, which is to say a stream consistency failure is a network problem, not an exchange refusal.

Order confirmation over a stream is a claim you have not verified. For anything consequential, the REST response to your own request is the more direct answer.

IBKR is neither of these

Worth stating because the vocabulary does not transfer. The TWS API is a TCP socket to a running desktop application, not a WebSocket and not REST. It is persistent and event-driven like a stream, and it carries order placement like a request API.

Its practical constraints are unlike both: TWS or IB Gateway must be running and logged in; ports are 7496/7497 for TWS live/paper and 4001/4002 for Gateway live/paper; up to 32 simultaneous API connections, with client ID 0 recommended for order management.

The Client Portal Web API is the REST option, and it substitutes a different constraint: its own local gateway, 10 requests/second per username, and daily re-authentication with no automated path.

A shape that works

  • Stream market data, your order updates, and position changes.
  • REST for placing, cancelling and amending.
  • REST to reconcile after every reconnect, and after any ambiguous failure.
  • Reserve REST budget for cancels, unavailable to data refresh.
  • Never auto-retry an order — a timeout means the outcome is unknown, not that it failed.

That last point connects the two halves. The reason to keep REST budget free is so that when something goes wrong, you can still ask what actually happened — and asking is the only safe thing to do before you act again.

FAQ

Should I place orders over WebSocket?

Some venues support it, and the appeal is latency. But the REST response to your own request is the most direct confirmation available, and for most people the latency difference is not the binding constraint. Start with REST for orders and move only if you have measured that it matters.

Does WebSocket count against my rate limit?

Not against REST weight, but streams have their own limits — connection counts, subscription counts and message rates. Hyperliquid documents a maximum of 10 WebSocket connections, 30 new connections per minute, 1000 subscriptions and 2000 messages per minute; Bybit returns 20003 for “too frequent requests under the same session”. Different budget, still a budget.

How do I keep my state correct across reconnects?

Reconcile over REST after resubscribing rather than assuming continuity. Check sequence numbers where the venue provides them. A gap during a reconnect produces silently wrong state, which is more dangerous than an outright error because nothing surfaces it.

Why does my new Hyperliquid account run out of requests so fast?

Because request allowance is earned by volume — one request per 1 USDC traded cumulatively, on top of an initial 10,000-request buffer. A new address has only the buffer, so exploratory polling can exhaust it before any trading happens. The generous-looking IP limit does not help.