
From Polling to Push: A Builder's Guide to Hyperliquid WebSockets
By CMM Team - 01-Jul-2026
From Polling to Push: A Builder's Guide to Hyperliquid WebSockets
Every Hyperliquid bot starts the same way. A loop, a sleep timer, and a REST call that fires every few seconds. It works, until it doesn't. The moment you start tracking more than a handful of assets, polling becomes the bottleneck you didn't plan for: burnt rate limits, stale data between intervals, and an architecture that scales linearly with every asset you add.
WebSockets solve this by flipping the model. Instead of your bot asking the server "has anything changed?" thousands of times per hour, the server tells your bot the moment something changes. One persistent connection replaces thousands of individual requests, and your bot reacts to market events as they happen rather than discovering them seconds or minutes late.
This guide walks through how to wire Hyperliquid's native WebSocket API into a trading bot, how to handle the reconnection edge cases that catch most builders off guard, and how to layer in pre-computed analytics from HyperTracker's push delivery so your bot has both raw market data and cohort-level intelligence flowing in simultaneously.
The polling problem at scale
REST polling is the right starting point for most bots. It's simple, stateless, and easy to debug. A swing trading bot that checks cohort positioning and funding rates a few times per hour is going to be fine with REST for its entire lifecycle. The architecture is straightforward and the request volume stays manageable.
The problems start when you fan out. If you're tracking ten assets with a one-second refresh target, that's 36,000 requests in a single hour. At thirty assets, you're above 100,000. Hyperliquid's public API has a shared weight budget of 1,200 per minute, and individual info queries cost between 2 and 20 weight units for most endpoints (with some specialized endpoints costing up to 60). Even at the lighter end, a ten-asset bot polling once per second will burn through that budget in a matter of minutes.
The other problem is latency. With one-second polling, your data is always between zero and one second stale. Most of the time, you're asking "did anything change?" and getting back the same answer. WebSockets eliminate that wasted bandwidth entirely, because the server only sends data when there's actually something new to send.
Hyperliquid's WebSocket channels
Hyperliquid exposes a single WebSocket endpoint at wss://api.hyperliquid.xyz/ws for mainnet (with a testnet mirror at wss://api.hyperliquid-testnet.xyz/ws). Once connected, you subscribe to specific data feeds by sending JSON messages.
The available subscription types cover the core data a trading bot needs:
- AllMids: Latest mid-prices for every listed asset. One subscription gives you a continuous feed of all prices without needing to poll per-coin.
- L2Book: Orderbook snapshots for a specific coin. Useful for bots that need depth data to size entries or gauge liquidity.
- Trades: Real-time fill data. Every trade that executes on the exchange shows up here.
- Candle: OHLCV candles at intervals from 1-minute through 1-day. The server pushes a new candle close as it happens.
- UserEvents: Your own fills, funding payments, and liquidation events. This is the feed that tells your bot whether its orders have been filled.
A subscription message looks like this:
{
"method": "subscribe",
"subscription": {
"type": "allMids"
}
}
For an L2Book subscription on a specific coin:
{
"method": "subscribe",
"subscription": {
"type": "l2Book",
"coin": "BTC"
}
}
The server responds with a subscription acknowledgment that includes a snapshot of the current state (tagged with isSnapshot: true), so your bot can hydrate its local state immediately without a separate REST call.
Keeping connections alive
Hyperliquid closes idle WebSocket connections after 60 seconds of silence. Your bot needs to send a heartbeat ping every 20 seconds to keep the connection open. The message is minimal:
{"method": "ping"}
This is easy to implement but surprisingly common to forget. Many builders wire up the subscription logic, test it in a low-traffic environment, and assume the connection is stable. Then their bot goes silent during a quiet overnight session, the server drops the connection, and the bot misses the Asian session open because nobody handled the reconnect.
Plan for reconnection: it will happen
Hyperliquid's documentation is explicit: disconnections happen periodically and without announcement. Your bot must treat reconnection as a normal operational event. Here's the flow that production bots use:
- Detect the disconnect. Either a ping timeout (no pong response within a reasonable window) or a WebSocket error/close event.
- Wait with exponential backoff. Start at one second, double each retry. This prevents your bot from hammering the server during an outage and getting rate-limited on top of the original problem.
- Reconnect and re-subscribe. Open a fresh WebSocket connection and resend all your subscription messages. The server will reply with new snapshots.
- Process the snapshots. These are tagged
isSnapshot: trueand contain the current state for each subscribed feed. Use them to rebuild your local state. - Reconcile with REST. If the disconnect lasted more than a few seconds, query the Info API to fill any gaps. Fills and user events can be retrieved via REST to ensure nothing was missed during the outage.
The critical detail is step five. Snapshots give you the current state, but they don't replay the events you missed. If a position was opened and closed during the disconnect, the snapshot shows neither. A quick REST query after reconnection catches those edge cases.
Multi-asset monitoring patterns
The biggest architectural win from WebSockets is multi-asset monitoring. A REST-based bot that tracks thirty assets needs thirty separate polling loops (or one loop with thirty sequential requests). A WebSocket-based bot subscribes to AllMids once and gets updates for every asset through a single connection.
For more granular data, you can mix subscription types on the same connection. A typical multi-asset bot might subscribe to:
- AllMids for price feeds across the entire market
- L2Book for the three or four assets it actively trades (depth data for sizing)
- Trades for those same assets (to detect large fills in real time)
- UserEvents to track its own order fills and funding payments
That's roughly ten subscriptions total, handling everything a multi-strategy bot needs. The same data via REST polling at one-second intervals would require dozens of requests per second.
A minimal Python connection manager
Here's the skeleton of a WebSocket connection manager using Python's websockets library. This handles heartbeats, automatic reconnection, and message routing:
import asyncio
import json
import websockets
WS_URL = "wss://api.hyperliquid.xyz/ws"
class HyperliquidWS:
def __init__(self, subscriptions):
self.subscriptions = subscriptions
self.ws = None
async def connect(self):
while True:
try:
async with websockets.connect(WS_URL) as ws:
self.ws = ws
await self._subscribe_all()
await asyncio.gather(
self._heartbeat(),
self._listen()
)
except websockets.ConnectionClosed:
print("Disconnected. Reconnecting...")
await asyncio.sleep(1)
async def _subscribe_all(self):
for sub in self.subscriptions:
await self.ws.send(json.dumps({
"method": "subscribe",
"subscription": sub
}))
async def _heartbeat(self):
while True:
await self.ws.send('{"method": "ping"}')
await asyncio.sleep(20)
async def _listen(self):
async for msg in self.ws:
data = json.loads(msg)
self._route(data)
def _route(self, data):
channel = data.get("channel")
if channel == "allMids":
self.on_price_update(data["data"])
elif channel == "l2Book":
self.on_book_update(data["data"])
elif channel == "trades":
self.on_trade(data["data"])
This is intentionally simplified. A production version would add exponential backoff, per-channel state tracking, REST-based gap reconciliation after reconnects, and error handling for malformed messages. But the core pattern is here: connect, subscribe, heartbeat, listen, reconnect on drop.
Layering in analytics: market data plus intelligence
Raw market data tells your bot what is happening: price moved, a fill occurred, the orderbook shifted. But it doesn't tell your bot who is driving the move. Is this a whale accumulating? Are the consistently profitable traders leaning the same direction? Is the Leviathan cohort (wallets holding $5M or more in perp equity) building a position while retail is selling?
This is where analytics push delivery comes in. Our data classifies every wallet on Hyperliquid into 16 behavioral cohorts: eight by account size (Shrimp through Leviathan) and eight by all-time PnL track record (Giga-Rekt through Money Printer). The cohort metrics update every five minutes, which means your bot can combine tick-level market data from Hyperliquid's native WebSocket with cohort positioning intelligence from HyperTracker's push delivery.
The architecture looks like this: Hyperliquid's WebSocket feeds price, trade, and orderbook data directly to your bot for tick-level reactions. HyperTracker delivers pre-computed analytics (cohort positioning, smart money alerts, liquidation risk scores, order flow summaries) via webhooks on the Flow tier ($799/mo) and Stream tier ($1,999/mo). Native WebSocket delivery from HyperTracker is coming soon, with the streaming infrastructure in active development now. Your bot fuses both data streams and makes decisions with both raw market data and behavioral intelligence.
For example, imagine your bot sees a sudden price dip on the Hyperliquid Trades feed. The raw data says: price dropped. Our cohort data, delivered via webhook, says: Money Printer wallets (the cohort with +$1M or more in all-time profit) increased their long exposure during the dip. That's a very different signal than if Giga-Rekt wallets (the cohort with the worst all-time PnL) were the ones buying.
When REST is still the right answer
WebSockets add complexity: connection management, heartbeat loops, reconnection logic, state reconciliation. For many bots, that complexity isn't justified.
REST polling is the better choice when your bot checks positions or signals infrequently (a few times per hour or less), when you're executing trades (Hyperliquid's Exchange API is REST-only for order placement), when you're building a daily reporting tool or portfolio tracker, or when you're prototyping and want the simplest possible architecture.
The hybrid pattern is what most production systems converge on. Use REST for order execution and account management. Use WebSockets for real-time market data. Use HyperTracker's REST API or push delivery for analytics, depending on how frequently you need cohort updates.
| Data Type | Best Delivery Method | Why | | --- | --- | --- | | Price feeds, fills, orderbook | WebSocket (Hyperliquid native) | Tick-level freshness, low overhead at scale | | Order placement, cancellations | REST (Hyperliquid Exchange API) | Request-response model fits execution semantics | | Cohort positioning, smart money signals | REST polling or push (HyperTracker) | Analytics refresh every 5 minutes, push for threshold alerts | | Liquidation risk, leaderboard changes | REST or webhooks (HyperTracker) | Event-driven: only relevant when a threshold crosses | | Historical data, backtesting | REST (HyperTracker) | Batch queries over months of fills and positions |
Common mistakes and how to avoid them
Having shipped bots that use both patterns, a few failure modes keep recurring.
No reconnection logic
The most common WebSocket bug is the one you don't notice. Your bot connects, subscribes, and runs fine for hours. Then the server drops the connection (routine maintenance, network hiccup, Hyperliquid node rotation), and the bot sits in silence, processing nothing, while you assume it's still running. Always implement reconnection with exponential backoff. Log every disconnect so you can audit gaps later.
Ignoring snapshots
When you reconnect and re-subscribe, the server sends a snapshot of the current state tagged with isSnapshot: true. Some bots discard these and only process incremental updates, which means their local state is permanently stale after every reconnect. Process the snapshot to rebuild your state, then switch to processing incremental updates.
Mixing up REST and WebSocket for execution
Hyperliquid's WebSocket delivers market data only. Order placement goes through the REST Exchange API and requires an EIP-712 signed request. If you try to send orders over WebSocket, nothing happens. Your bot's data pipeline and execution pipeline should be separate loops.
Polling analytics at tick speed
Cohort-level analytics (like smart money positioning or liquidation risk) don't change on every tick. Our data refreshes every five minutes, which is the right granularity for behavioral cohort analysis. Polling cohort endpoints every second wastes your rate limit budget and doesn't get you fresher data. Match your polling frequency to the data's actual refresh rate, or switch to webhook/push delivery and let the server notify you when something changes.
Build with both: market data and cohort intelligence
HyperTracker's API gives your bot pre-computed cohort analytics across 16 behavioral segments. Start with REST polling on a free tier (100 requests/day) and upgrade to webhooks (Flow, $799/mo) or WebSocket push (Stream, $1,999/mo) as your bot's data needs grow.
The graduation path
Most successful Hyperliquid bots follow a predictable trajectory. They start with REST polling because it's easy to reason about and fast to prototype. Once the bot works and the edge is proven, the builder graduates to WebSockets for the market data layer because the request volume becomes unsustainable with polling. The analytics layer tends to follow a similar path: start by polling HyperTracker's REST endpoints every few minutes, then switch to push delivery when the bot needs to react to cohort shifts more immediately.
The graduation isn't about which protocol is "better." It's about matching the delivery method to the data's natural rhythm. Price data changes on every tick, so it belongs on a WebSocket. Cohort analytics update every five minutes, so REST or push delivery both work. Order execution is a discrete request-response action, so REST is the natural fit.
Wire each data stream to the delivery method that matches its cadence, and you get a bot that scales without burning through rate limits, misses nothing during reconnections, and makes decisions with both raw market data and behavioral intelligence. That's the architecture most builders end up at. The question is whether you get there by design or by accident after a few painful outages.