ResourceGuide

BBO vs L2Book vs L4Book: the different types of orderbook streaming on Hyperliquid

If you're building on Hyperliquid — a trading bot, a market maker, a dashboard, or an analytics pipeline — one of your first decisions is how to consume real-time orderbook data. Hyperliquid's book can be streamed at several levels of detail, and picking the wrong one means either burning bandwidth on data you don't need or missing the granularity your strategy depends on.

This guide compares the four ways to stream Hyperliquid orderbook data over the Hydromancer WebSocket API: BBO (top of book), L2Book (price-level snapshots, raw or aggregated), L2BookDiff (incremental level updates), and L4Book (order-by-order updates with user addresses). We'll look at what each message contains, how the latency and bandwidth trade-offs stack up, and which stream fits which use case.

Hyperliquid orderbook streams at a glance

StreamWhat it is
bboJust the best bid and best ask — top of book, nothing else
l2BookThe orderbook aggregated by price levels — price, total size, and order count per level
l4BookEvery individual order in the book, with order IDs and user addresses

All of these ride Hyperliquid's block cadence: a new block lands roughly every 70 milliseconds, and book updates are published per block.

Orderbook not what you need? The full map of every real-time stream — trades, TP/SL orders, TWAPs, ledger events — is in our Hyperliquid data feeds guide.

What is BBO? Top-of-book price streaming

BBO (best bid and offer) is the leanest Hyperliquid market data stream: a single message containing the current best bid and best ask for one coin, sent only when the top of book changes. If you just need live prices — a ticker, a mid-price feed, spread monitoring, or alerting — BBO gives you real-time data at a fraction of the bandwidth of a full orderbook stream.

{
    "method": "subscribe",
    "subscription": { "type": "bbo", "coin": "BTC" }
}

Each update carries a bbo array of exactly two elements, [best_bid, best_ask], where each side is a price level (px, sz, n — price, total size, and order count) or null if that side of the book is empty.

You can also omit coin to receive BBO updates for every market on Hyperliquid over a single subscription. The all-coins firehose requires the bboAll add-on on your API key and accepts a marketTypes filter (more on that below).

What is L2Book? Hyperliquid L2 orderbook streaming

L2 (level 2) data aggregates the book by price: each level tells you the price (px), the total resting size at that price (sz), and how many orders make it up (n), for both sides of the book — bids sorted descending, asks ascending. This is the workhorse stream for most Hyperliquid orderbook data needs.

The defining property of l2Book is that it's stateless: every message is a complete snapshot, delivered on block cadence (~70ms) whenever the book changes. There's nothing to reconstruct and no state to maintain — you simply overwrite what you had. That's why its cursor field is always "0": there's no replay, because nothing is ever missing from a snapshot.

{
    "method": "subscribe",
    "subscription": {
        "type": "l2Book",
        "coins": ["ETH", "BTC"]
    }
}

Depth is configurable with nLevels: 1 (effectively BBO), 10, 20 (the default), or 50 levels per side.

Raw vs aggregated L2 data

By default you get raw price levels. For charting and display you can ask the server to aggregate prices with nSigFigs (2–5 significant figures) and, when nSigFigs=5, an optional mantissa of 2 or 5 to snap the last digit. Bids round down and asks round up, so aggregation never makes the book look tighter than it is — with nSigFigs=5, mantissa=2, a bid at 70325 becomes 70324 while an ask at 70325 becomes 70326.

Aggregated snapshots arrive ~15ms after L4 versus ~5ms for raw, so keep raw feeds for anything latency-sensitive and use aggregation where it belongs: rendering a clean depth ladder. When you run multiple l2Book subscriptions at different aggregation levels, each message echoes back its nSigFigs/mantissa so you can tell the streams apart.

Streaming every Hyperliquid market at once

Omit coins and l2Book becomes an all-markets firehose (requires the ws:l2BookAll add-on). Two options matter here:

  • marketTypes filters delivery by market type: "perp", "spot", "outcome" (Hyperliquid's HIP-4 outcome markets), or ["*"] to auto-include every type the server tracks. Omitting it defaults to ["perp"] only — spot and outcome markets never appear unless you opt in.
  • pushMode: "delta" sends a full snapshot of all coins once on subscribe, then only the coins whose books changed each block. It carries the same data as "full" mode for roughly 80% less bandwidth, and it's what unlocks nLevels: 50 on the firehose. Each message is still a complete snapshot for the coins it contains — just key a local map by coin and overwrite.
{
    "method": "subscribe",
    "subscription": {
        "type": "l2Book",
        "marketTypes": ["perp", "outcome"],
        "pushMode": "delta"
    }
}

L2BookDiff: incremental updates for local orderbooks

If you want full L2 depth at the lowest possible bandwidth, l2BookDiff streams per-level diffs instead of snapshots: your client applies each change to a locally maintained book. It's also faster than snapshots — about 2ms behind L4. The trade-off is that you own the state: you're building and updating the book rather than replacing it.

Intermission · Need history, not streams?

Everything on this page is about live data. If you're backtesting or doing research, you can get all Hyperliquid historical data for free with Reservoir — our free, forever Hyperliquid data archive: every fill, 1-second candle, daily snapshot, and 20-level orderbook history, straight from an open S3 bucket. No API key, no signup.

Read about Reservoir

What is L4Book? Order-by-order Hyperliquid orderbook data

L4 data is the full-granularity view of the Hyperliquid orderbook: every individual order, not just price-level totals. Where L2 tells you “12.4 ETH is bid at 3245.5 across 3 orders,” l4BookUpdates tells you which three orders, each with its unique order ID (oid) and the user address (user) that placed it.

l4BookUpdates is not part of the original Hyperliquid API — it's a Hydromancer endpoint added for builder convenience.

Updates stream per block, tagged with block height and timestamp, as a list of diffs:

Diff typeMeaningFields
newNew order placedcoin, oid, user, side, px, sz
updateOrder size changed (partial fill)coin, oid, sz
removeOrder filled or cancelledcoin, oid

This is the stream for market makers and high-frequency strategies: it's the lowest-latency Hyperliquid orderbook feed, and order-level detail is what makes queue-position modeling, order-flow analysis, and tracking specific wallet addresses possible at all. Subscribing to all markets requires the l4BookUpdatesAll add-on. For a full walkthrough, see our L4 orderbook streaming builder guide.

Latency: which Hyperliquid orderbook stream is fastest?

Every stream is driven by Hyperliquid's ~70ms block cadence; the difference is how quickly each format is derived and pushed once a block lands:

  1. l4BookUpdates — fastest; raw order events straight off the block.
  2. l2BookDiff — ~2ms after L4.
  3. l2Book (raw) and bbo — ~5ms after L4.
  4. l2Book (aggregated) — ~15ms after L4, the cost of server-side price aggregation.

If you're optimizing for a low-latency Hyperliquid API, the rule of thumb is simple: trade with L4, build books with diffs, display with aggregated L2. Independent numbers are on our Hyperliquid data latency benchmark.

Bandwidth: keeping your Hyperliquid data feed lean

Ranked from lightest to heaviest: BBO (only sends on top-of-book change) → L2BookDiff (only the levels that changed) → L2Book snapshots (complete book each time — use pushMode: "delta" on the firehose for ~80% savings) → L4Book (every order event on the exchange). Don't pay for granularity you won't read: a dashboard polling mid-prices over L4 wastes almost all of its bandwidth.

Which orderbook stream should you use?

A note on naming before the picker: BBO, L2, and L4 are generic orderbook concepts, but the concrete streams on this page — bbo, l2Book, l2BookDiff, l4BookUpdates, the firehoses and their add-ons — are the Hydromancer implementation over the Hyperliquid book, so they're named according to our WebSocket API. Some of them (l4BookUpdates, l2BookDiff) don't exist on the official Hyperliquid API at all.

  • Market making / HFT l4BookUpdates. Lowest latency, order IDs and user addresses for queue and flow modeling.
  • Maintaining a local orderbook (execution systems, analytics) → l2BookDiff. Full depth, minimal bandwidth, ~2ms behind L4.
  • Stateless services (serverless functions, simple bots, anything that shouldn't hold state) → raw l2Book. Every message is the whole truth.
  • Charting and UI depth ladders → aggregated l2Book with nSigFigs.
  • Tickers, alerts, spread monitors bbo.
  • Whole-exchange coverage (screeners, market-wide analytics) → the all-markets firehose with pushMode: "delta", plus the matching add-on (ws:l2BookAll, bboAll, or l4BookUpdatesAll).

Need a one-off book rather than a stream? The REST API serves point-in-time L2 snapshots and L4 snapshots too.

How to subscribe: Hyperliquid WebSocket API basics

All streams share one connection: wss://api.hydromancer.xyz/ws?token=YOUR_API_KEY. Wait for the connected message, send your subscriptions, and answer server pings with a pong to keep the socket alive.

const WebSocket = require('ws');

const ws = new WebSocket(`wss://api.hydromancer.xyz/ws?token=${process.env.HYDROMANCER_API_KEY}`);

ws.on('message', (raw) => {
    const msg = JSON.parse(raw);
    if (msg.type === 'connected') {
        ws.send(JSON.stringify({
            method: 'subscribe',
            subscription: { type: 'l2Book', coins: ['ETH', 'BTC'] }
        }));
    } else if (msg.type === 'ping') {
        ws.send(JSON.stringify({ type: 'pong' }));
    } else if (msg.type === 'l2Book') {
        const [bids, asks] = msg.data.levels;
        console.log(`${msg.data.coin} bid=${bids[0]?.px} ask=${asks[0]?.px}`);
    }
});

Every subscription carries a gap-free seq counter, so detecting a dropped message is a simple integer check. The same WebSocket also serves the rest of Hyperliquid's real-time data — trades-style fills, candles, activeAssetCtx, and allMids — so one connection can feed your whole stack.

FAQ: Hyperliquid orderbook streaming

What is the difference between L2 and L4 orderbook data?

L2 aggregates orders by price level — you see each price with total size and order count. L4 is order-by-order: every individual order with its own ID and the user address behind it. L2 answers “what does the book look like?”; L4 answers “who is in the book, and where?”

How often does the Hyperliquid orderbook update?

Hyperliquid produces a block roughly every 70ms, and orderbook streams publish per block. Snapshots and diffs are sent for coins whose books changed that block; bbo only fires when the best bid or ask actually moves.

What is the fastest way to stream Hyperliquid orderbook data?

l4BookUpdates — it's the lowest-latency feed, delivering raw order events as each block lands. l2BookDiff follows about 2ms later, raw l2Book about 5ms later.

What is the most bandwidth-efficient way to track Hyperliquid prices?

bbo. It sends a message only when the top of book changes, and each message is two price levels. For full-depth data at low bandwidth, use l2BookDiff; for a market-wide feed, use the l2Book firehose in pushMode: "delta".

Can I stream the orderbook for every Hyperliquid market over one connection?

Yes. Omit the coins field on l2Book, bbo, or l4BookUpdates to get an all-markets firehose. Each requires its add-on (ws:l2BookAll, bboAll, l4BookUpdatesAll), and the marketTypes filter controls which market types are delivered.

Do orderbook streams cover Hyperliquid spot and HIP-4 outcome markets?

Yes — but not by default. All-markets subscriptions default to perps only; add "spot" and/or "outcome" to marketTypes (or pass ["*"]) to receive spot and HIP-4 outcome markets as well.

How do I know if I missed a message?

Every subscription's seq is gap-free, so a jump in seq means a lost message. Because l2Book is stateless, recovery is trivial: reconnect and the next snapshot makes you whole. On a delta-mode firehose, resubscribe to receive a fresh full snapshot and resync.

Do I need an API key to stream Hyperliquid orderbook data?

Yes — the WebSocket authenticates with a token in the connection URL. You can get an API key here and check rate limits and user limits for your tier.

Ready to build? Grab an API key, open a socket to wss://api.hydromancer.xyz/ws, and start with the stream that matches your use case — the full reference for bbo, l2Book, l2BookDiff and l4BookUpdates lives in the Hydromancer docs.