REST API vs WebSockets vs WebSocket API - tiagosiebler/awesome-crypto-examples GitHub Wiki

All exchanges are starting to support a WebSocket API. First, let's explore what this means versus traditional WebSockets & REST APIs.

REST APIs

A REST API is a type of API that allows you to communicate with a server via HTTP request.

Workflow

Usually, each REST API request will go through the full HTTP request life cycle:

  1. DNS Lookup: Resolve the domain to an IP address, via a connection to your DNS (to fetch a record for that domain).
  2. TCP handshake: Open a TCP connection to the REST API web server.
  3. TLS handshake: Verify the connection to the server is secure, while asking the server to prove its identity. Read more about it here.
  4. Finally, send the HTTP request and wait for the response.
  5. Terminate the request.

Drawbacks

Increased latency

Each HTTP request to a REST API is typically stateless. Since a new connection is typically made for each HTTP request, there is some avoidable latency while repeatedly opening/negotiating/closing connections for each HTTP request. If you're latency sensitive, you may benefit from leveraging HTTP keep-alive (if supported), or making use of WebSockets.

Increased rate limit consumption

If you need regular updates from the exchange, consider using WebSockets as a consumer, instead of making frequent REST API calls. This would both:

  • reduce the latency of any state updates (such as market data or order updates).
  • reduce the consumption of available rate limits.

WebSockets

Pub/Sub WebSockets

Originally, most WebSockets provided by crypto exchanges follow the Pub/Sub design pattern. They allow you to connect, as a consumer, and subscribe to specific events (e.g. candle/order/position/trade updates). New events would then be received by your consumer when they become available, without any additional requests from your consumer (after you have subscribed).

Workflow

The exact workflow might vary per exchange, but for most exchanges, this is typically the workflow:

  1. DNS Lookup: as above, see explanation above.
  2. TCP handshake: as above, see explanation above. Open a connection to the WebSocket server.
  3. TLS handshake: as above, see explanation above.
  4. WS upgrade/handshake: a small request to upgrade to the WebSocket protocol.
  5. Send messages: e.g. authenticate, send subscription requests to individual topics (e.g. BTCUSDT 1m spot market klines), etc.
  6. Messages will be automatically sent from the WebSocket server to your consumer, as new data becomes available (e.g. order filled, candle closed, balance changed, etc) – depending on the topics you have subscribed to.

While the first steps of the connection life cycle are very similar to the REST API workflow, the core advantage is that once the connection is open & you have subscribed, receiving new data as it becomes available is completely passive. Instead of regularly polling the REST API for new candles, the WebSocket server will send you new candles as soon as they become available. This allows you to follow a reactive design, instead of proactively using rate limits to poll the REST API.

Benefits

  • Lower latency for new data, since you only follow the "new connection" life cycle once.
  • Lower rate limit usage, since you don't need to regularly poll for new data.
  • Allows reactive programming. You don't need to regularly poll for new data. Instead, expect to be given new data as soon as it is available.

Drawbacks

  • Temporary disconnection risks.
    • WebSockets require an active & healthy connection. Depending on your network conditions as well as server-side stability, WebSockets can get disconnected.
    • It's important to plan for this by:
      • making regular requests (heartbeats) to check that the server is still connected.
      • closing & replacing dead connections, as soon as possible.
      • if a connection is replaced, query for any missed data, if mission critical.
    • This is automatically handled for you, if you're using any of my Node.js/TypeScript/JavaScript SDKs.
      • Each SDK's WebSocket client will automatically resubscribe to any topics you were previously subscribed to.
      • Each SDK's WebSocket client will automatically emit the "reconnected" event, if this happens.
      • You can use this event as a trigger to check for any missed data, if mission critical.
      • See the following example for a demonstration of a state check after a connection is reconnected: TODO: account state example here when ready.
  • Pub/Sub only.
    • Typically, this design is for Pub/Sub only.
    • Normally you cannot send requests (commands) such as submitting new orders or querying your balance, using these WebSockets. Until recently...
  • Increased complexity.
    • Since WebSockets require a persistent connection, there is some additional complexity in managing healthy connections.
    • As above, this is automatically handled for you, if you're using any of my Node.js/TypeScript/JavaScript SDKs.

WebSocket API

All exchanges have started to support a WebSocket API. This is exactly as it sounds. It has the capabilities of a REST API, via a WebSocket connection. They allow you to connect to the WebSocket server once, authenticate, and then reuse the same connection for all API calls without the added latency of opening new connections and signing each individual request.

Workflow

The exact workflow might vary per exchange, as with the pub/sub WebSockets, but for the most part they are very similar:

  1. DNS Lookup: as above.
  2. TCP handshake: as above.
  3. TLS handshake: as above.
  4. WS upgrade/handshake: as above.
  5. Send requests: as above, although you can also send other commands supported by the exchange's WebSocket API, such as submitting a new order, checking your balance, etc. Exact functionality varies per exchange.
  6. Receive responses: responses to individual requests are sent from the server to the client on the same connection. Usually, this includes enough information to identify which request the reply is connected to.

Benefits

  • Lower latency for all API calls, since you only follow the "new connection" life cycle once. With some exchanges, you also only have to authenticate once – so you benefit from even lower request latency due to the avoided request sign with every command.

Drawbacks

  • Temporary disconnection risk, as above.
    • This is automatically handled for you, if you're using any of my Node.js/TypeScript/JavaScript SDKs.
    • The WS API integration in my SDKs is designed around promises. Any requests are wrapped in a promise.
    • If the connection drops before the promise resolves/rejects, any pending promises are rejected on the assumption that the request failed.
  • Only some APIs are available via WebSocket API.
    • This depends per exchange.
    • Usually only some of the REST API functions are available via the WebSocket API.
    • For the remainder, you have to continue using the REST API.
  • Increased complexity.
    • Since WebSockets require a persistent connection, there is some additional complexity in managing healthy connections.
    • Since all API requests/responses are sent on one shared WebSocket connection, there is additional complexity in recognising which responses are for which request.

Conclusion

Benefits > drawbacks

While there is no universal answer, by using WebSockets as much as possible, you can:

  • significantly reduce the latency of your integration with crypto exchange APIs
  • significantly reduce your rate limit consumption while polling for data via REST API, by instead leveraging WebSockets for any new data / state changes.

You may still need to use the REST API (or the WS API) to query for any data you don't have yet (or that your system missed during a brief disconnection window), but that is still a significant improvement compared to relying completely on the REST API.

SDKs make it easy

While it may seem WebSockets have a number of drawbacks (due to the added complexity of maintaining an active connection & handling asynchronous workflows), with the right tools, a lot of this is handled for you automatically.

For subscribing to updates on the market or your account, use the available WebSockets and let the information flow to you. Example for Bybit: https://github.com/tiagosiebler/accountstate/blob/master/examples/bybit-futures.ts#L137-L159

For the WebSocket API, use the promise-driven approach supported by my Node.js/TypeScript/JavaScript SDKs. The complexity is handled for you, and you can simply call a function and await the result, very much like working with a REST API. Your system does not need to care that a WebSocket is involved. Example for Bybit: https://github.com/tiagosiebler/bybit-api?tab=readme-ov-file#websocket-api---sending-orders-via-websockets