Exceptional single-core performance
Ibex delivers leading per-core performance on common columnar queries. Multi-core execution is being expanding from that baseline.
Ibex
Ibex gives DataFrame pipelines their own compact language. Explore in a notebook (Jupyter, R/dplyr, or Ibex's own web UI) and compile it to C++ when the pipeline needs to ship.
Explore
Ibex is designed for interactive data exploration. Type a pipeline into the REPL, evaluate the result, adjust your code, and repeat.
The same pipeline can run in a notebook, script, or compiled binary unchanged, without switching languages or API.
This session groups 10 million generated ticks and shows the actual output and measured runtime on my workstation.
Sample captured locally using :timing
on in the REPL: 10M generated ticks. Timings vary by machine and
run. Run Ibex live in your browser →
Ibex delivers leading per-core performance on common columnar queries. Multi-core execution is being expanding from that baseline.
Named clauses describe each transformation, and columns are
referenced directly by name. In Ibex you write px, not
pl.col("px").
Use Python or R notebooks, the web UI, or a REPL for exploration and modelling, then use C++23 codegen for native binaries. Type errors are caught before the pipeline runs.
Performance
Ibex is built for the hard part of table work: grouped aggregation, rolling time windows, joins, filters, null handling, and reshaping. The benchmark suite compares each query against the same operation in Polars, DuckDB, ClickHouse, DataFusion, pandas, data.table, and dplyr.
Polars: 63.8 ms. DataFusion: 35.2 ms. Ibex single-threaded: 34.4 ms.
Polars: 290 ms. DuckDB: 66.1 ms. DataFusion: 49.1 ms.
Polars: 146 ms. DuckDB: 1.24 s. DataFusion: 14.0 s.
Ibex parallelises some operators by default. The benchmark page shows every
engine at its default settings alongside a single-threaded run of each —
including ibex-st, which makes Ibex's own threading gain
visible and gives a same-core comparison against the other engines.
The vocabulary
Clauses compose inside a pipeline. Start with these common operations, then see the tutorial or reference for the full syntax.
filter
select
update
map
by
order
Use map { name = expr } when work is genuinely row-wise,
including ordered file conversions and other effectful extern calls.
The same script runs in the REPL, whole-script planner, and generated
C++ binary. Scalar lookups may be null, so optional configuration can be
recovered explicitly with coalesce.
Install & run
Download a prebuilt release and start exploring immediately.
Option A — download a release
Grab the prebuilt ibex REPL and bundled plugins, unpack,
and run — no toolchain required.
Run your first pipeline
# Unpack the archive for your platform, then:
./ibex --plugin-path ./plugins
import "data_gen";
let ticks = gen_ticks(100);
// Order symbols by total volume
ticks[
select { traded = sum(volume) },
by symbol,
order { traded desc },
];
Where to go next
Start with installation and a first pipeline, then work through language, data, and integration topics.
Interactive timings and memory use against Polars, DuckDB, ClickHouse, DataFusion, pandas, and R.
Follow runnable data workflows, comparisons, and time-series examples.
A guided walk through every clause, with runnable snippets for deeper evaluation.