Skip to content

WebSocket (Disk-Sync)

The Disk-Sync WebSocket feed delivers raw Hyperliquid replica commands as they are committed to the L1. Each message contains the hex-encoded binary representation of a replica command, providing the highest-fidelity data feed available through the Aleatoric platform.

This feed is designed for teams that need to reconstruct full chain state independently — custom indexers, replay-based backtesting infrastructure, protocol-level analysis, and MEV research.

Availability: Enterprise and Quant tiers only. Contact sales@aleatoric.systems to enable access.

RegionEndpointNotes
US (East US 2)wss://disk.grpc.aleatoric.systemsPrimary
JP (Japan East)wss://disk-jp.grpc.aleatoric.systemsLive production edge

The US and JP production endpoints use TLS-encrypted WebSocket connections (wss://). Plaintext ws:// is not supported.

The Disk-Sync WebSocket follows a four-phase lifecycle:

The client opens a WebSocket connection and authenticates via either an HTTP header or a query parameter. Authentication is validated during the WebSocket upgrade handshake; invalid credentials cause the server to reject the upgrade with HTTP 401.

Header authentication (recommended):

const ws = new WebSocket("wss://disk.grpc.aleatoric.systems", {
headers: { "x-api-key": "ak_live_your_key_here" }
});

Query parameter authentication:

const ws = new WebSocket(
"wss://disk.grpc.aleatoric.systems/?api_key=ak_live_your_key_here"
);

Header-based authentication is preferred because query parameters may appear in access logs and proxy caches. If you must use query parameters (e.g., browser environments), rotate keys periodically.

Python (websockets library):

import websockets
import asyncio
URI = "wss://disk.grpc.aleatoric.systems"
API_KEY = "ak_live_your_key_here"
async def connect():
headers = {"x-api-key": API_KEY}
async with websockets.connect(URI, extra_headers=headers) as ws:
async for message in ws:
handle_message(message)

After a successful handshake, the server sends a single confirmation frame:

{
"type": "connected",
"feed": "disk-sync",
"ts_ms": 1710345600000
}

This confirms the client is authenticated and the stream is active. No explicit subscribe message is required — the connection itself constitutes a subscription to the full replica command feed.

Once connected, the server pushes messages continuously. Each message represents one replica command as committed by the Hyperliquid sequencer:

{
"type": "replica_cmd",
"seq": 482910553,
"raw_hex": "0a1f0a1d08b5e3c9a10612170a15...",
"ts_ms": 1710345600123,
"ingest_ts_us": 1710345600123456,
"publish_ts_us": 1710345600123512
}

Messages arrive in strict sequence order. If the client falls behind (recv buffer full), the server will terminate the connection rather than skip messages.

The server may close the connection for any of these reasons:

Close CodeReasonAction
1000Normal closure (server shutdown / deploy)Reconnect immediately
1008Policy violation (auth revoked, tier downgraded)Check API key status
1011Unexpected server errorReconnect with backoff
1013Try again later (overloaded)Reconnect with backoff

The client should also handle unexpected TCP disconnects (no close frame received).

FieldTypeDescription
typestringAlways "replica_cmd"
seqintegerMonotonically increasing sequence number. Gaps indicate missed messages (reconnect and replay from last known seq).
raw_hexstringHex-encoded binary payload of the Hyperliquid replica command
ts_msintegerUpstream timestamp in milliseconds since Unix epoch
ingest_ts_usintegerBridge ingest timestamp in microseconds since Unix epoch
publish_ts_usintegerBridge publish timestamp in microseconds since Unix epoch

The raw_hex field contains the serialized Hyperliquid replica command. This is the same binary format written to the Hyperliquid node’s disk replica log. Each command encodes one of:

  • Order placement / cancellation — new limit or market orders, cancel-by-id, cancel-all
  • Trade execution — matched fills with price, size, and maker/taker addresses
  • Liquidation — forced position closure with mark price and insurance fund delta
  • Funding settlement — periodic funding rate application across all open positions
  • Oracle update — spot oracle price submissions from validators
  • Withdrawal / deposit — L1-to-L2 bridging events

The binary format is Protocol Buffers-based. Decoding requires the Hyperliquid replica command schema, which is available in the Hyperliquid open-source node implementation. Aleatoric does not alter, reorder, or filter commands — what the node commits is what the feed delivers.

The microsecond timestamp pair enables measurement of internal processing latency:

Δt=tpublishtingest[μs]\Delta t = t_{\text{publish}} - t_{\text{ingest}} \quad [\mu s]

For the Disk-Sync feed, Δt\Delta t is typically <100  μs< 100\;\mu s since the command is forwarded with minimal transformation (hex encoding only).

Because the feed is ordered and gap-free, reconnection logic must account for the possibility of duplicate or missed messages. The recommended approach:

import asyncio
import websockets
import json
import random
URI = "wss://disk.grpc.aleatoric.systems"
API_KEY = "ak_live_your_key_here"
async def stream_with_reconnect():
last_seq = None
attempt = 0
while True:
try:
headers = {"x-api-key": API_KEY}
async with websockets.connect(
URI,
extra_headers=headers,
ping_interval=30,
ping_timeout=10,
close_timeout=5,
) as ws:
attempt = 0 # Reset on successful connection
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "connected":
print(f"Connected to {msg['feed']}")
continue
if msg["type"] == "replica_cmd":
seq = msg["seq"]
# Detect gaps
if last_seq is not None and seq != last_seq + 1:
print(f"Gap detected: expected {last_seq + 1}, "
f"got {seq}")
# Handle gap: fetch missing via REST backfill API
# or flag for reconciliation
last_seq = seq
process_command(msg)
except (websockets.ConnectionClosed, OSError) as e:
attempt += 1
delay = min(2 ** attempt, 60) + random.uniform(0, 1)
print(f"Disconnected ({e}), reconnecting in {delay:.1f}s...")
await asyncio.sleep(delay)
def process_command(msg):
"""Decode and handle a replica command."""
raw_bytes = bytes.fromhex(msg["raw_hex"])
# Decode using Hyperliquid protobuf schema...
pass
  1. Exponential backoff with jitter. Start at 1 s, double up to 60 s, add uniform random jitter in [0,1][0, 1] s to avoid thundering herd on server recovery.
  2. Track seq locally. On reconnect, compare the first received seq with your last processed seq to detect gaps.
  3. Do not reconnect on 1008 (policy violation). This indicates an authentication or authorization problem that retrying will not resolve.
  4. Use WebSocket ping/pong. Set ping_interval=30 to detect dead connections faster than TCP keepalive.
  5. Size your recv buffer. The feed can burst to thousands of messages per second during high-activity periods. If your processing pipeline cannot keep up, consider buffering to disk.

Replay the full command stream into a custom database (PostgreSQL, ClickHouse, etc.) to build bespoke analytics tables, cross-reference on-chain events with off-chain signals, or maintain a shadow state for auditing.

Record the raw hex stream to object storage (e.g., Azure Blob, S3) and replay it deterministically through a local node to reconstruct any historical state. Because the feed preserves exact sequencer ordering, replay produces bit-identical state.

Analyze sequencer behavior, block timing distributions, gas dynamics, and transaction ordering at the replica command level. The raw format exposes structure not visible through higher-level RPC or gRPC interfaces.

Combine ingest_ts_us / publish_ts_us timestamps with your own receive timestamps to build a complete latency profile across the data path:

ttotal=tclient_recvtupstreamt_{\text{total}} = t_{\text{client\_recv}} - t_{\text{upstream}}

tbridge=tpublishtingestt_{\text{bridge}} = t_{\text{publish}} - t_{\text{ingest}}

tnetwork=ttotaltbridget_{\text{network}} = t_{\text{total}} - t_{\text{bridge}}

This decomposition isolates network transit time from processing overhead, enabling precise co-location and routing decisions.