All articles
Hyperliquid·November 26, 2025·5 min read

Cutting Order Latency on Hyperliquid WebSocket API to Sub-50ms

Hyperliquid's WebSocket feed delivers L2 order book updates and fills faster than its REST endpoints, but connection management, message parsing, and signing overhead still introduce hidden latency. This guide benchmarks Python vs Rust clients, shows how to pipeline order placement with book updates, and covers reconnect strategies that avoid missed fills.

Cutting order latency on the Hyperliquid WebSocket API to sub-50ms is achievable, but it requires understanding exactly where time gets spent — from the moment a book update arrives to the moment your signed order hits the exchange. The bottlenecks are not where most people expect. Connection management, JSON parsing, and EIP-712 signing all contribute more than raw network round-trip, and fixing the wrong one first wastes weeks.

What the Hyperliquid WebSocket Feed Actually Delivers

Hyperliquid exposes a WebSocket endpoint at wss://api.hyperliquid.xyz/ws that pushes L2 book snapshots and diffs, trade prints, user fills, and order status updates. The alternative — polling the REST endpoint — adds a full request cycle per update. On a healthy connection from a co-located VPS, you can expect book diffs to arrive in 5–15ms from when the match engine generates them.

Subscribe to l2Book for the symbol you care about, and userFills for fill confirmations. Subscribing to both on a single connection is important: each connection carries overhead, and Hyperliquid's fair-use limits penalise excessive subscriptions. Keep one long-lived connection, not a connection per subscription.

Python vs Rust: Where the Real Gap Is

A naive Python client using websockets + json.loads introduces 8–20ms of pure parsing overhead on a typical L2 book message. Add the GIL contention if you're sharing a thread with order logic, and you're routinely sitting at 30–40ms before you've even thought about signing.

Benchmarks on a 2-core VPS (same region as Hyperliquid's infra):

Layer Python (asyncio) Rust (tokio + tungstenite)
JSON parse + deserialize 8–18ms 0.3–0.8ms
EIP-712 signing 5–12ms 0.2–0.4ms
Total before network send 14–30ms 0.5–1.2ms

If you need to stay in Python, two changes buy significant time: replace json with orjson (3–5x faster deserialisation), and move signing off the hot path using a pre-built signing key cache. For anything where sub-20ms matters, Rust is the right choice — the async overhead is negligible and signing becomes effectively free.

Pipelining Book Updates with Order Placement

The single largest latency mistake is a sequential pipeline: receive update → compute new quote → sign → send. Each step waits for the previous one to complete.

The better architecture keeps a continuously updated local order book and pre-computes quote candidates in the background. When a book diff arrives, you check whether your pending quote is still valid against the new state. If it needs to change, you have a pre-signed order template ready for the new price level — only the price and nonce fields need updating, not a full re-sign from scratch.

In practice this looks like:

  • Maintain a local L2 book that applies diffs incrementally (never reconstruct from scratch on every update)
  • Keep a ring buffer of pre-signed order templates at price levels ±N ticks from your current quote
  • On each diff, determine if your posted order is still within tolerance — if not, pull from the buffer and send
  • Refresh the buffer asynchronously, never blocking the receive loop

This pipeline structure drops the send latency from 30–60ms to 8–15ms in a Python implementation and to under 5ms in Rust.

EIP-712 Signing Overhead and How to Reduce It

Every order on Hyperliquid requires an EIP-712 signature with your wallet's private key. In a Python eth_account implementation this takes 5–12ms per order. At quote update rates of 10–20 per second, you will miss your window on fast-moving books.

Two concrete approaches:

Pre-sign a batch. At market open or after a repositioning event, pre-sign a set of cancel-and-replace pairs for the price range you expect to operate in. Store them as ready-to-send byte strings. This is only viable for strategies with predictable price ranges (tight market-making), not for reactive directional entries.

Use a local signing sidecar. Run a minimal Rust binary that exposes a Unix socket, accepts (price, size, side, nonce) tuples, and returns signatures. Your Python strategy code stays readable; signing becomes a 0.5–1ms IPC call instead of a 10ms in-process computation. This is the architecture we use in the Hyperliquid market-making bot built for active trading desks.

Reconnect Strategy That Does Not Miss Fills

WebSocket connections drop. How you reconnect determines whether you have a gap in fill data that causes inventory desync.

The naive approach — reconnect and re-subscribe on disconnect — has a blind spot: any fill that occurred during the gap will not arrive via userFills because that subscription is stateful and only pushes new events.

The correct approach:

  1. On disconnect, record the timestamp of the last received message
  2. On reconnect, immediately call the REST endpoint GET /info with type: "userFills" and a startTime set to your last message timestamp minus a 2-second buffer
  3. Replay any fills received via REST that are newer than your last WebSocket fill
  4. Resume the WebSocket subscription

This gives you a complete fill record even across multi-second outages. Pair this with a heartbeat ping every 20 seconds — Hyperliquid will close idle connections after ~60 seconds of silence, and detecting that fast matters for strategies that are flat but still need accurate fill history.

Co-location and Network Path

Software optimisations plateau once you're below 10ms of local processing time. At that point, network path dominates. Hyperliquid's matching engine runs on their own infrastructure; the closest cloud region (as of mid-2025) for lowest RTT is typically a US-East datacenter, though this should be validated with your own ping and WebSocket round-trip measurements rather than assumed.

A 5ms RTT from a well-placed VPS means your minimum end-to-end latency floor is roughly 10ms (one round trip for the book update, one for the order). Sub-50ms is very achievable from the right region. Sub-10ms requires co-location arrangements that are not publicly available on Hyperliquid today — plan your strategy around realistic numbers.

For strategies where latency is the primary edge, the infrastructure layer matters as much as the code. The infra and data pipelines service covers exactly this — custom websocket clients, co-located execution services, and the monitoring layer to know when something drifts.


If you want a production Hyperliquid bot with sub-50ms order placement, signed fill reconciliation, and a live dashboard — built to the standard described here — get in touch.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Hyperliquid#WebSocket#Trading Bots#Low Latency#Python#Rust#Order Execution#Perps