Skip to main content
hyperliquid.perp_market_metrics_hourly is the venue-wide hourly market table for Hyperliquid perpetual futures. Grain: one row per (coin, block_hour), covering both first-party markets (coin = BTC) and HIP-3 builder-deployed markets (coin = xyz:TSLA); spot and HIP-4 outcome markets are out of scope. coin is the join key to perp_market_details; market_symbol repeats across dexes, so never join on it. This table, not perp_trades, is the volume figure to quote: hyperliquid.perp_trades holds both legs of every match, so its raw SUM(notional_usd) is exactly twice the volume reported here. The candle, volume and count columns here are measured off the taker leg, so each match is counted once. The participant counts and fee_usd deliberately span both legs — unique_traders is distinct accounts on either side, and fee_usd nets the legs, because a rebated maker fee is negative.

Table schema

Why hourly, and when a row exists

Funding is one global round per hour that covers every market and every account at a single block, so an hour is one clean position snapshot — there is no finer cadence at which open interest is well defined. A row exists if the market had either a trade or an open position in the hour. That is why an illiquid market with zero trades still reports open interest: the trade columns are zero-filled (volume_usd = 0, trades_count = 0) while the candles and vwap stay NULL, because there was no price. The newest hour is partial by construction. Trades are still accumulating, and open_interest_*, open_positions and funding_* stay NULL until the top-of-hour round clears ingestion, observed at 30–75+ minutes. Filter block_hour < date_trunc('hour', now()) for complete hours only.

Flows and stocks have different history floors

Flow columns are aggregated from perp_trades, which starts 2025-07-27. Stock columns — open_interest_units, open_interest_usd, open_positions, funding_rate, funding_rate_annualized, funding_paid_usd — come from the venue’s hourly funding events, which start 2025-09-27 (both floors measured 2026-08-21). Rows in between carry trade columns only, with every stock column NULL.
Open interest, open position counts and funding rates cannot be reconstructed from fills under any circumstances — a fill records a change in a position, never the standing position of every account. There is no backfill for the two-month gap.

Open interest is published both-sides

open_interest_units is longs plus shorts, matching what the Hyperliquid UI and API publish. Classical one-sided open interest is exactly half of it. open_interest_usd prices those units at the market’s last trade at or before the hour, carried forward on hours the market did not trade. The Hyperliquid UI prices open interest at mark instead, so the two differ by the trade-to-mark basis.

Funding direction and magnitude

funding_rate is the rate as it settled for that hour, not the forward-looking rate shown beside the funding countdown in the UI, which prices the round about to close. A long pays at a positive rate. funding_paid_usd is the magnitude that changed hands, taken from the paying side. The receiving side is the same figure — open interest is balanced, so funding nets to zero within a market — which means the column is a gross flow, not a net, and direction has to come from the sign of funding_rate.

Classification and administrative fills

Curated metadata (market_category, asset_class, asset_type, underlying_ticker, builder_name) is deliberately not stored here, so that a reclassification never rewrites this table — join perp_market_details on coin for it.
volume_usd includes administrative fills — the engine’s force-close of every position when a builder DEX delists a market, and vault position netting. Neither is trading, and neither can be excluded at this grain: for a tape without them, aggregate perp_trades with is_taker AND fill_type NOT IN ('settlement', 'vault_netting').
For the reporting grain use perp_market_metrics_daily, which re-aggregates from fills rather than summing these rows — daily distinct account counts cannot be summed out of hourly ones.