You asked for Hyperliquid archival data because a backtest, a compliance export, or a book reconstruction job needs history. If you treated that request like an EVM archive node, you bought the wrong product.
On Ethereum and most L2s, "archive" means eth_getBalance and eth_call at a historical block. On Hyperliquid, the equivalent is a product choice. Native node records live in S3 prefixes. Processed ticks and OHLCV bars are derived from those records. Wallet, builder, and market queries go through the Hyperliquid Index. Public JSON-RPC is the wrong door for almost all of that work.
Pick the product before anyone writes a parser. That is the whole decision.
The docs live at Historical Data. That page is the inventory. This post is how to use it without mixing prefixes, treating consensus rounds as block numbers, or paging an Index method as if it were a dump.
Hyperliquid history is not an EVM archive node
Hyperliquid has two read surfaces that get collapsed in vendor conversations.
HyperEVM is the Solidity environment. Historical eth_call, traces, and account state follow the usual archive-node rules. If that is your problem, start with The Hidden Costs of Archive Nodes and a HyperEVM RPC endpoint.
HyperCore is the trading engine. Fills, order statuses, book diffs, TWAP events, and ABCI state are node-written records, not EVM trie nodes. Dwellir preserves those records in source formats and offers processed datasets on top. Asking a HyperEVM archive node for a 2025 BTC fill tape will not work. Asking S3 for eth_getStorageAt will not work either.
The old /docs/hyperliquid/archival-data URL now redirects to historical data. The operator work is still the same: name the feed, name the window, then pick the product that can actually serve it.

Pick the product before you pick the parser
Most failed Hyperliquid history projects start by decompressing .lz4 objects and only then asking what the job was. Start with the job, then pick the prefix.
| If you need | Use |
|---|---|
| Native blocks, fills, order events, book diffs, misc events, TWAP events, snapshots, or ABCI state | S3 historical data |
| Full-resolution trades in CSV or Parquet | Tick data |
| Wallet, builder, market, or historical-order queries over an API | Hyperliquid Index fills |
| 1s, 1m, or 5m price bars and exports | OHLCV data |
| Live L2/L4 books, BBO, and trades | Order Book WebSocket |
| Live raw feeds or derived V3 market streams | gRPC streaming |
The cheap mistake is using gRPC or the public WebSocket to backfill months of history. Those are live paths. The expensive mistake is pulling the entire replica_cmds prefix when you only needed userFillsByTime for one address.
Public Hyperliquid RPC is still rate-limited at 100 requests per minute. It is a prototype door, not an archive. For production historical reads, use the products above. See How to Get a Hyperliquid RPC Node when the job is live HyperEVM access instead of Core history.

The S3 inventory operators actually query
Dwellir's historical bucket is a set of prefixes with different start dates and object shapes. Treat the table as a coverage contract, not a marketing list.
| Prefix | From | To | Object shape |
|---|---|---|---|
replica_cmds | 2025-01-12 | Current | LZ4-compressed native records |
node_trades | 2025-03-22 | 2025-06-21 | .lz4 |
node_fills | 2025-05-25 | 2025-07-27 | .lz4 |
node_fills_by_block | 2025-07-27 | Current | hourly .lz4 |
node_order_statuses_by_block | 2026-01-22 | Current | hourly .lz4 |
node_raw_book_diffs_by_block | 2026-01-22 | Current | hourly .lz4 |
misc_events_by_block | 2026-07-01 | Current | hourly .lz4 |
node_twap_statuses_by_block | 2026-07-01 | Current | hourly .lz4 |
orderbook_snapshots | 2026-04-29 | Current | .json.lz4 |
periodic_abci_states | 2026-04-14 | Current | .rmp.lz4 |
Native JSON and JSONL payloads are LZ4-compressed. Decompress before you parse. Generated order-book snapshots use .json.lz4. Periodic ABCI state uses .rmp.lz4 and contains RMP-encoded node state, not JSON. If your pipeline assumes every object is JSONL, periodic_abci_states will fail first.
Most current *_by_block feeds use an envelope with local_time, block_time, sequential block_number, and a feed-specific events array. That envelope is the unit of work for fills, order statuses, book diffs, misc events, and TWAP statuses once those prefixes are current.
Field-level references for the live stream counterparts sit under blocks, fills, order statuses, raw book diffs, misc events, and TWAP statuses.
Three fill generations, one parser trap
Fills are the prefix operators get wrong most often. The tape is not one schema from genesis. It spans three stored generations:
| Prefix | Native shape | Useful fields |
|---|---|---|
node_trades | Trade record with a side_info array for participants | coin, side, time, px, sz, hash, participant order IDs |
node_fills | User address paired with a fill object | Price, size, direction, PnL, fee, order ID, trade ID, and fee token |
node_fills_by_block | Block envelope containing per-account fill events | Current fill fields plus block context and builder attribution |
Observed objects for these generations overlap. The From and To bounds are coverage windows, not mutually exclusive schema cutover dates. If you switch parser on calendar day, you will double-count some hours and drop others.
Select the parser from the object prefix and record shape, then deduplicate downstream. For processed analysis, tick data converts node_fills_by_block into CSV or Parquet from 2025-07-27 onward. For query access, use the Index fills API rather than scanning every hourly object for one wallet.

Do not treat replica_cmds rounds as block numbers
replica_cmds is the oldest prefix in the bucket. It starts 2025-01-12 and still runs. The records contain abci_block and execution responses.
abci_block.round is a consensus round. It can skip. It is not the sequential block_number used in *_by_block envelopes.
That distinction shows up again in the Index. Fill methods expose txIndex as the fill's block-local position in the node_fills_by_block event array. It is not a replica_cmds-compatible action index. If you join Index pages to replica_cmds on (round, action index), the join is wrong even when both sides look numeric.
Use replica_cmds when you need native blocks and execution responses. Use *_by_block prefixes when you need sequential block context. Do not mix the two identifiers in one primary key.
Reconstructing a book takes a seed plus ordered diffs
Raw book diffs are not a book. Order-book reconstruction needs a known state seed, then ordered application of node_raw_book_diffs_by_block.
The documented seed is an orderbook_snapshots object, generated from periodic ABCI state. Snapshots start 2026-04-29. Periodic ABCI state starts 2026-04-14. Raw diffs start 2026-01-22.
That date split is an operator constraint, not a footnote. You can store diffs from late January 2026. You cannot reconstruct a starting book from diffs alone, and you do not have documented snapshot objects until late April 2026. A research job that asks for "full L4 history from Q1" needs an explicit answer: diffs without a seed are not a reconstructable book.
For live books, skip the archive path. Use the Order Book Server. Archives are for replay. Live L2/L4 is a streaming product. Hyperliquid latency explained covers when historical snapshots are enough and when they are an overbuy.
Use the Index when you do not want a dump
S3 is the right answer when you are building a warehouse. It is the wrong answer when a product feature needs "this wallet's fills last Tuesday" or "this builder's liquidations in a one-hour window."
The Hyperliquid Index serves those reads over REST-style /info and JSON-RPC on the documented host api-hyperliquid-index.n.dwellir.com, using the same API-key-in-path model as the rest of Dwellir. Current fill-family methods include userFills, userFillsByTime, builderFills, allFills, allFillsByTime, TWAP slice and summary methods, liquidation fills, and historicalOrders / historicalOrdersByTime.
Three billing and paging facts change capacity planning:
- Fill history is billed by the number of fill objects returned, not by HTTP request. A page of 2,000 fills is 2,000 credits. An empty array is 0.
limitis capped at 2,000 for fill-row methods and 500 for TWAP summaries.allFillsByTimerequiresendTimeand caps the window at 1 hour. Keep the sameendTimeuntil that hour is exhausted. Advancing the window before the cursor is done will drop rows.
By-time methods resume with cursor in time_txIndex form. txIndex is the block-local fill position described above. For userTwapSummariesByTime, resume with lastFillTime_txIndex because summary rows expose lastFillTime, not time. Historical orders use statusTimestamp_txIndex_oid so rows that share a timestamp and txIndex are not skipped.
Optional coin filters are exact server-side market filters. They are not substring search. Discover the symbol first.
OHLCV is bars, not an archive substitute
OHLCV is derived from the same canonical fill history, then materialized as sparse 1s, 1m, and 5m candles. The OHLCV archive floor is 2025-07-27T08:00:00Z, matching the first node_fills_by_block entry. Larger intervals are not materialized. Derive them from the shipped bars if you need them.
Sparse means empty intervals are omitted. Do not bill or store as if every second of the month exists. A dense 30-day 1s series would be 2,592,000 candles before gaps. Actual returned counts are lower, and range endpoints page up to 5,000 candle objects.
Market symbols are not interchangeable with S3 coin strings:
| Market type | Symbol format | Example |
|---|---|---|
| Native perp | asset name | BTC |
| Spot | @INDEX | @142 |
| HIP-3 perpDex | prefix:ASSET | hyna:ETH |
Spot uses the pair index, not the token name, except PURR. If you pass UBTC into OHLCV you will not get @142. Look up names through the Info endpoint: meta for perps, spotMeta for spot, perpDexs for HIP-3.
Candles preserve executed fill prices, including sweep prints across multiple levels. That can produce small high or low differences versus another public candlestick feed. If you need the execution-faithful tape, that is intended. If you need the venue's compressed bars, do not assume they match.
Live lookups and WebSocket streams use the Index host with your API key. Full-history CSV or Parquet exports go through the dashboard OHLCV Data tab. DIY backfill still exists in the archive backfill guide.
Tick data is the columnar middle
Tick data sits between native S3 and OHLCV. It is processed from node_fills_by_block into analysis rows:
timestamp, pair, price, size, side, trade_id, user_address, block_number
Timestamps are milliseconds from the source time field. Order rows by block_number and timestamp. Group matches on (pair, trade_id). When deduplicating individual fill rows, include user_address or order identity so maker and taker legs that share a trade ID are not collapsed. Trade IDs are not a global sequence.
Extended fields (dir, closedPnl, fee, crossed, builder, builderFee) are optional. Ask for them when the job is PnL, builder attribution, or spread-crossing analysis. Skip them when the job is a simple tape.
Tick files are a support-delivered product today. Confirm processed availability for requested symbols and dates rather than assuming every S3 hour has a matching Parquet partition. REST query access is documented as coming soon, so do not design a production API client against it yet.
An operator checklist before you file the request
- Name the workload. Replay, warehouse, wallet query, or bars. One product per job. Mix only at the application layer.
- Name the window against prefix coverage. A book reconstruction that starts before
2026-04-29has diffs without documented snapshots. Fills before2025-07-27are notnode_fills_by_blockand are not OHLCV. - Name the identifier. Sequential
block_numberfor*_by_block. Consensusroundforreplica_cmds.timeplustxIndexfor Index by-time pages. Never one key for all three. - Name the market symbol format.
meta/spotMeta/perpDexsfirst, then S3, Index, or OHLCV. - Name the access path. OHLCV exports: dashboard. S3, tick data, and other historical products: email support@dwellir.com with prefix or product, date range, preferred format, and use case.
If you only needed a snapshot every few minutes, stay on historical data and skip streaming. If you needed one builder's fills, stay on the Index and skip S3. If you needed native ABCI state, stay on periodic_abci_states and do not pretend it is JSONL.
The infrastructure question for Hyperliquid history is not "do you have archive." It is which historical product matches the read. Name the product first. The parser, the bill, and the backtest get simpler after that.
For teams that need the native bucket, processed ticks, or Index capacity sized for by-time windows: contact the Dwellir team. To start with OHLCV exports, create an account and open the Hyperliquid OHLCV tab.


