Aperiodic
CryptoRWANew
Catalog
Markets
Pricing
Get Started

Architecture · Live cluster

The pipeline behind every metric

A fleet of redundant producers, two replicated message brokers, a streaming-SQL engine we wrote in Rust, and an archive that never skips a batch. This is how a print on an exchange becomes a message on your live stream and a row in your backtest: captured twice, kept once, and windowed on the clock you could actually have traded on.
Trace the clusterBrowse the catalog

Shown: net taker flow (buys minus sells) summed over each venue’s perpetuals, per minute, 18:00–01:00 UTC on 10 Oct 2025, buys above each venue’s line and sells below it on a square-root scale; the deepest sell minute, 21:13 UTC with $1.9B net sold across the three venues, is orange · built with flow 1m

From window close to publish
50 ms
Producers streaming, 2 per feed
200+
On both message brokers
High Availability

The live cluster

Venues

Capture

Broker

Compute

Store

Deliver

Live path
Producers → Message broker (raw) → Stream engine → Message broker (metrics) → Kafka
Each window published once, 50 ms after it closes
Archive path
Message broker (raw) → Raw archivers → Object storage → Pre-signed URL API
Offsets committed only after the upload is acknowledged

Hover or select a component to trace what feeds it and what it feeds.

  1. 01 · Venues

    Binance

    USDⓈ-M futures

    2 connections

    Every public market-data channel we capture from Binance is streamed by two redundant producers, each on its own connection.

    Channels
    Trades, quotes, L2 book, mark, index, funding, OI, liquidations, long/short ratios
    If one fails
    The other producer’s connection carries the channel on its own, so no event is missed.

    OKX

    Perpetual swaps

    2 connections

    Every public market-data channel we capture from OKX is streamed by two redundant producers, each on its own connection.

    Channels
    Trades, quotes, L2 book, mark, index, funding, OI, liquidations, long/short ratios
    If one fails
    The other producer’s connection carries the channel on its own, so no event is missed.

    Hyperliquid

    Perpetuals, HIP-3 included

    2 connections

    Hyperliquid perpetuals, with the HIP-3 builder-deployed markets on the trade and quote feeds. Every channel is streamed by two redundant producers.

    Channels
    Trades, quotes, L2 book, mark, index, funding, OI
    If one fails
    The other producer’s connection carries the channel on its own, so no event is missed.
  2. 02 · Capture

    Producers

    Rust · 200+ instances

    AB200+ streaming · 2 replicas per feed

    A fleet of over two hundred producers streams in parallel. Each feed is captured by its own process twice over, by two replicas on separate nodes, stamped with our capture time the moment it arrives and normalized to one schema across venues.

    Fleet
    200+ instances, streaming at once
    Redundancy
    2 replicas per feed, never on the same node
    Timestamps
    Exchange time and our capture time on every record
    Sharding
    Large feeds split by a stable hash of the contract
    If one fails
    Replica set B keeps publishing every event on its own, so no feed has a gap.
  3. 03 · Broker

    Message broker (raw)

    5 nodes · High Availability

    5 nodes

    Every raw record lands on a replicated, Kafka-compatible message broker that the stream engine and the archivers read independently. Both replicas of a feed publish here; the broker keeps the first copy of each event. A restarted consumer resumes from its own committed offset.

    Availability
    High Availability: replicated across 5 nodes
    Storage
    Local NVMe on dedicated nodes
    Dedup
    At the broker, on each event’s ID: two copies in, one out
    Topics
    raw.<channel>.<venue>, 5 partitions each
    Exposure
    No external listener
    If one fails
    Every partition is copied to other nodes. One of them takes over as leader, and nothing already written is lost.
  4. 04 · Compute

    Stream engine

    Rust · streaming SQL

    ↻10 s checkpoints

    Our own engine, written in Rust, runs every metric as SQL generated from one registry: tumbling windows on capture time, ASOF joins, and order books rebuilt in-process for the L2 metrics.

    Windows
    15s to 1d, keyed on capture time
    Emit
    50 ms after a window closes
    State
    Checkpointed every 10 s; a restart resumes from it
    Output
    Each window exactly once, never a partial bar
    If one fails
    It is restarted and resumes from its last checkpoint. Windows it already published are not published again.

    Raw archivers

    Rust · Kafka → Parquet

    ↻Replays on restart

    Archivers decode the raw records into Parquet and upload them in batches. The Kafka offset is committed only after the upload is acknowledged.

    Batches
    Close at 1 MiB or 30 s
    On a crash
    The open batch is replayed: never a gap
    Layout
    <channel>/exchange=/year=/month=/day=/hour=/
    If one fails
    It is restarted and replays the open batch, whose offsets were never committed, so no file is skipped.
  5. 05 · Store

    Message broker (metrics)

    3 nodes · High Availability

    3 nodes

    Every metric, venue and interval has its own versioned topic on a second message broker, apart from the raw one, so customer reads never compete with ingestion.

    Availability
    High Availability: replicated across 3 nodes
    Topics
    <metric>.v<N>.<venue>.<interval>
    Cross-venue
    Top-3 aggregates next to each venue
    Access
    TLS + SASL, ACLs per customer
    If one fails
    Every partition is copied to other nodes. One of them takes over as leader, and nothing already written is lost.

    Metric archivers

    Rust · Kafka → Parquet

    ↻Replays on restart

    Archivers read every metric topic and write it to Parquet in batches. As on the raw side, the Kafka offset is committed only after the upload is acknowledged.

    On a crash
    The open batch is replayed: never a gap
    Layout
    By metric, venue, interval and day
    If one fails
    It is restarted and replays the open batch, whose offsets were never committed, so no file is skipped.

    Object storage

    Colocated + cloud · Parquet

    Colocated + cloud

    Raw and metric archives, each written by its own archivers, land as partitioned Parquet on replicated object stores, both colocated and cloud-managed.

    Stores
    Colocated and cloud-managed, both replicated
    Files
    Immutable once published
    Raw
    Partitioned by venue, day and hour
    Metrics
    Partitioned by metric, venue, interval and day
    If one fails
    Every object is kept redundantly across colocated and cloud-managed stores, so a failed disk, server or store loses nothing.
  6. 06 · Deliver

    Kafka

    Institutional · TLS + SASL

    3 brokers

    On Institutional plans, subscribe to the metric topics with any Kafka client. Credentials are per customer and scoped to the metrics you are entitled to.

    Format
    One JSON row per closed window
    Auth
    SASL over TLS
    If one fails
    Clients reconnect to another broker and resume from their committed offset.
    Learn more →

    WebSocket

    Edge · JSON

    Cloudflare edge

    A bridge forwards the topics customers subscribe to into an edge Worker, so a script or a browser streams metrics with an API key and one subscribe message.

    Auth
    Your data API key
    Transport
    wss://, served at the edge
    If one fails
    Served from Cloudflare’s network. A client that drops reconnects and subscribes again.
    Learn more →

    Pre-signed URL API

    History · Parquet

    Cloudflare edge

    A history request resolves to short-lived pre-signed URLs, so files stream straight from object storage. The Python SDK and AI agents use the same API.

    Delivery
    Short-lived URLs to Parquet files
    Clients
    Python SDK, curl, AI agents
    If one fails
    Requests are served from Cloudflare’s network, and the URLs point straight at replicated storage.
    Learn more →

Design decisions

Most market-data pipelines are good enough until a connection drops, a pod restarts or a definition changes. These are the choices that keep ours correct when they do.

Windows close on our clock, not the exchange’s

Every window keys on the moment our producer received the event, not the timestamp the exchange stamped on it. An exchange-time window cannot close until a late enough exchange clock reading arrives, which puts the whole network leg and every exchange batching delay inside the watermark. Keying on capture time also means a bar holds what you could actually have seen by its close: no look-ahead in a backtest.

Every window once, never half a window

The engine checkpoints its state and source positions every 10 seconds and remembers the last window it published to each topic. After a crash it resumes from the checkpoint and suppresses what it already wrote. A pipeline with no checkpoint withholds any window it cannot compute whole, so the worst case is a missing bar, never a wrong one.

Two producers, one record

200+ producers stream at once, and every feed runs on two of them, on separate nodes, so a dropped connection or a lost node never opens a hole in the data. Both publish the same events, and the message broker drops the second copy by each event’s ID, before any consumer reads it.

The archive commits after the upload

Archivers commit their Kafka offset only once object storage has acknowledged the Parquet file. A crash mid-batch replays the batch instead of skipping it, and every file gets a unique name, so a retry never overwrites another writer’s file.

Definitions never change underneath you

A running pipeline’s SQL is never edited in place. A changed metric ships as a new version that reads the same raw topics and publishes next to the old one, on its own topics and Parquet prefix. Each released version’s SQL hash is pinned, and the build fails if it would ever compute differently.

An engine built for this one workload

We replaced a general-purpose streaming database with our own engine: one Rust binary per pipeline, threads rather than async on the data path, columnar batches, and an order book rebuilt in-process so the L2 metrics are plain SQL.

Research on it, then trade on it

See every metric this cluster computes, or stream them into your own systems.

Browse the catalogStream it live

Shown: minute lows of the 465 Binance perpetuals, 20:40–22:00 UTC on 10 Oct 2025, with BTC’s path traced · built with ohlcv 1m

Aperiodic

Built from hundreds of terabytes of raw data and distilled into point-in-time metrics you can pull as parquet files. Plus the raw trades, quotes and derivatives data behind them.

Use Cases
  • Improve your backtest
  • Find new alpha
  • Execute smarter
Catalog
  • Full Catalog
  • Markets
  • Order Flow
  • L1 — Top of Book
  • L2 — Order Book
  • Market Data
  • Derivatives
  • Raw Data
  • RWA
  • Atlas Security Master
Developers
  • API Docs
  • Notebooks
  • For AI Agents
  • Changelog
  • Roadmap
  • llms.txt
Learn
  • Replays
  • Microstructure Guide
  • Architecture
  • Research Blog
  • FAQ
Compare
  • All vendors
  • vs. Tardis
  • vs. CoinGlass
  • vs. Kaiko
  • vs. Amberdata
Company
  • Pricing
  • Contact
  • Book a call
  • Terms of Service
  • Privacy Policy
  • Licensing
  • SLA

© Copyright 2026 Aperiodic. All Rights Reserved.

Aperiodic Limited · Registered in Ireland · Company No. 815273 ·
136 Capel Street, Dublin D01 T2C9, Ireland

Shown: minute closes of 847 perpetuals, 20:30–22:30 UTC on 10 Oct 2025, IOTX in orange · built with ohlcv 1m