Orderbook
L2 orderbook snapshots for every perpetual and spot market.
20-level L2 orderbook snapshots for every perpetual and spot market on Hyperliquid and all HIP-3 dexes. Each snapshot captures the top 20 bid and ask price levels at the time it was taken — price, total size at the level, and order count. Updated weekly.
Bucket: s3://hydromancer-reservoir (requester pays)
by_dex/{dex}/orderbook/1m/{asset_class}/date=YYYY-MM-DD/{coin}.parquetOne file per coin per day. {dex} is hyperliquid for native perps/spot, or the HIP-3 dex name (xyz, hyna, felix, …). {asset_class} is perps . Files are only created for dates with data.
Coin naming:
Perps (native):
BTC,ETH,SOL, …Perps (HIP-3): same as the coin (e.g.
NVDA,AAPL,SP500). Routed via the{dex}path segment.Spot (native):
@{pair_index}(e.g.@107,@142). The legacyPURR/USDCpair has its slash URL-encoded asPURR%2FUSDC.parqueton disk.
Schema
Each row is one complete orderbook snapshot. Bid and ask levels are stored as list columns (best price first), with up to 20 levels per side.
block_time_ms
int64
Block time in milliseconds since epoch (UTC)
block_number
uint64
Hyperliquid block number
bids
list<struct<px:string, sz:string, n:uint32>>
Bid levels, highest price first. px and sz are decimal strings for lossless precision; n is the order count at that level
asks
list<struct<px:string, sz:string, n:uint32>>
Ask levels, lowest price first. Same field semantics as bids
Why list-of-struct? One row equals one complete snapshot, which matches how you'd think about the book. Parquet physically stores bids.list.item.px, bids.list.item.sz, and bids.list.item.n as separate columns under the hood — so column pruning still works. A query that only reads bids[1].px (the best bid over time) only loads that one physical column.
Quick Start
DuckDB
Polars
Notes
Time ordering. Rows within each file are written in block order. You can iterate without sorting for streaming reconstructions.
Missing levels. If a side of the book has fewer than 20 populated price levels, the list simply contains fewer elements — no padding with zero/null entries.
Dex prefixes. The path's
{dex}segment is the authoritative dex identifier. HIP-3 coin names do not include thedex:prefix here — e.g. a Trade[XYZ] file forNVDAlives atby_dex/xyz/orderbook/1m/perps/date=…/NVDA.parquet.Scale. For context, a busy day for 602 markets produces ~866K rows total per day across all coins in the 1m cadence, roughly ~90 MB compressed.
Last updated