RUST CORE · DATAFUSION SQL · ARROW + PARQUET

Time-series DB for agents.
Backtesting for any asset

h5i-db is an embedded time-series database and event-driven backtesting engine for quantitative research. Built for AI agents, with native ASOF joins, OHLCV rollups, and high-throughput event replay.

cargo install h5i-db-cli
pip install h5i-db

High-speed analytical database for time-series.

A storage kernel and query engine tuned for the time axis: data is time-sorted on disk, pruned by manifest statistics before I/O, and queried through DataFusion SQL with native time-series operators. Version control, time travel, and previewable mutations come built in, so the speed never costs you safety.

Time-series SQL engine
Full SQL through DataFusion: joins, windows, CTEs, plus a native ASOF JOIN, time_bucket, vwap, wavg, and ewma. Storage is time-sorted, so bucketed aggregations stream instead of sorting.
Manifest pruning
Per-segment time ranges and column min/max live in the version manifest. Narrow time-range queries never open irrelevant files: 48 of 50 segments pruned before I/O in the benchmark, visible per query with --stats.
Fast, durable ingestion
3.2 million rows per second across 50 fsync-durable commits. Every write is an atomic compare-and-swap on a single HEAD: racing writers get an explicit version_conflict, never last-writer-wins.
Versioned storage and time travel
Immutable Parquet segments with per-version manifests, directly addressed by sequence. h5i('trades', 42) reads version 42 in O(1) and an RFC3339 timestamp reads as of a commit time in O(log V); named snapshots pin exact versions across tables, keeping a backtest reproducible forever.
Previewable mutations
--plan runs the full write path but stops before publish: exact affected rows, segments rewritten vs reused, before/after samples. plan apply is a metadata-only swap, and a mutation policy can force agents through review.
Crash-safe by construction
fsync-before-swap, checksums on every object, a manifest hash chain, and tests that kill the writer at every commit step. The old head survives, always. verify --deep re-checks the whole store.

High-throughput event-driven backtesting engine.

A replay kernel that reads the same versioned tables everything else queries. No export step: the pinned dataset, the run, and its results are one object, so a result stays attributable to the exact data it was produced from.

Event-driven replay kernel
One pass over the merged event stream, pulled lazily rather than materialised: memory stays flat whether a run covers an hour or a year. Order lifecycle, queue position, and latency are modelled, not assumed away.
Canonical venue tables
Kalshi, Polymarket, and Hyperliquid payloads decode into one set of tables: book_deltas, trades, bars, instruments, resolutions, funding. The kernel never learns which vendor a row came from.
Real fee curves and funding
Each venue's actual schedule, not a flat basis-point stand-in. Prediction-market fees curve with price rather than scaling with notional, and perpetual funding accrues against the position it was held in.
Point-in-time by construction
Pin a decision time and the frame that reaches pandas cannot contain rows stamped after it. Lookahead bias is ruled out by the read path, not by remembering to filter.
Every run is a fork
A run executes in its own fork and writes bt_orders, bt_fills, bt_positions, and bt_equity there. Forks share data instead of copying it, so a wide sweep costs close to nothing and discards cleanly.
Statistics that report their own reliability
Factor and performance metrics at alphalens and empyrical parity, plus deflated Sharpe, probability of backtest overfitting, and purged cross-validation, so a number found by searching is discounted for the search.

Fast where quant workloads live.

Two workloads, each measured against the tools it would replace, with storage and I/O included on every side.

2.2–4.7×
faster OHLCV than every engine
72×
repeat aggregates via warm version-aware states
1.9M
rows/s durable versioned ingest
1.1ms
cold read, any version
Database

20M trades and 5M quotes: Polars, DuckDB, pandas, and PyArrow over the identical h5i-db Parquet segment files, ArcticDB over its own LMDB store loaded with the same data.

workloadh5i-dbpolars 1.35duckdb 1.3pandas 2.3pyarrow 24arcticdb 6.19
time-range scan 0.01% (48/50 segments pruned)10.0 ms28.1 ms45.5 ms23.9 ms22.8 ms4.2 ms²
time-range scan 1%12.8 ms29.9 ms40.9 ms25.6 ms24.0 ms5.6 ms²
1-minute OHLCV + VWAP rollup1 558 ms7 309 ms7 237 ms5 115 ms7 121 ms3 504 ms
ASOF join trades × quotes (by symbol)1 548 ms1 485 ms11 566 ms6 624 msn/a¹7 008 ms
full aggregation (group by symbol)353 ms370 ms228 ms2 578 ms553 ms886 ms
ingest (50 durable versioned commits)1.9 M rows/sn/an/an/an/an/a
cold read of an old version1.1 msn/an/an/an/an/a
Backtesting

200k top-of-book events and 200 orders through each engine. Medians of three fresh-process runs after one warm-up, with every adapter verifying it saw all 200k events and submitted all 200 orders.

enginemeasured boundarymedianthroughput
h5i-dbdecoded records through the replay kernel65.7 ms3.05 M events/s
h5i-dbfull persisted run: scan, decode, fork, replay, write331 ms605 k events/s
NautilusTrader 1.230.0in-memory objects through BacktestEngine.run()767 ms261 k events/s
LEAN 11ba019f6first Slice callback to OnEndOfAlgorithm, disk-fed2 033 ms98.4 k events/s

The approval surface for your data.

h5i-db ui market.db serves a loopback-only review surface: pending plans with exact previews, apply and reject, a version timeline with audit badges, version diffs, and an SQL scratchpad that shows pruning on every query. Read-only unless started with --allow-mutations.

From install to a scored backtest.

CLI

$ cargo install h5i-db-cli $ h5i-db init market.db $ h5i-db create-table market.db trades --like ticks.parquet --time-column ts $ h5i-db ingest market.db trades ticks.parquet $ h5i-db query market.db "SELECT * FROM asof_join('trades','quotes','ts','ts','symbol')" $ h5i-db ui market.db # review surface on localhost

Python

$ pip install h5i-db >>> db = h5i_db.Database("market.db") >>> db.sql("SELECT * FROM h5i('trades', 42)").to_pandas() # time travel >>> plan = db.plan_delete_range("trades", start, end) >>> plan.apply() # preview first, commit second

Backtest (Python)

>>> from h5i_db import backtest, quant >>> backtest.create_signal_table(db) >>> db.append("signals", backtest.signal_table(orders)) # intent, not fills >>> run = backtest.run(db, "mom-v1", starting_cash=100_000.0, ... signals="signals", snapshot="q1-cut", fee_rate=0.02) >>> fork = db.fork(run["fork"]) # every run lands in its own fork >>> fork.read("bt_fills").to_pandas() # orders, fills, positions, equity >>> quant.from_levels(fork, "bt_equity").stats() # sharpe, max drawdown, ...

Quant-grade speed. Agent-grade safety.

One embedded database for backtests, live research, and the agents that run them. Rust core, DataFusion SQL, versioned Parquet storage. Apache 2.0, no server, no lock-in.