close
Skip to content

— Benchmarks

Measured,
not claimed

Machine
Apple M1 Pro, 8 cores, 16 GB, Node 25
Against
DuckDB 2.0 (@duckdb/node-api 2.0.0-r.1)
Vectro
b2a3033 · 2026-11-01
Load
Shared laptop: load 3–8 during the in-memory runs, up to 15 during the billion-row run. Ratios move by up to about ±30% between runs.
Method
Each system in its own process, best of 5 in memory and best of 3 on disk, every answer compared between the two.

In memory · 10M rows

The same SQL on 10M orders + 100K customers

The same SQL text in both, from filters and joins to window functions, percentiles, text functions and outer joins.

20/20

faster or level · best of 5, answers checked · compare/bench-sql.mjs

totals with a filter4.3 ms / 10.1 ms2.3× faster
group by region7.4 ms / 36.8 ms5.0× faster
join + filter + group19.8 ms / 32.8 ms1.7× faster
top 10 customers13.1 ms / 50.3 ms3.8× faster
distinct customers per month34.2 ms / 82.5 ms2.4× faster
top 20 rows by price9.1 ms / 25.3 ms2.8× faster
CASE inside SUM6.6 ms / 39.6 ms6.0× faster
IN (subquery)23.4 ms / 29.7 ms1.3× faster
correlated subquery16.8 ms / 61.4 ms3.7× faster
top 3 per region (RANK)38.2 ms / 139.3 ms3.6× faster
ROW_NUMBER over all rows128.5 ms / 220.5 ms1.7× faster
running total by day9.8 ms / 17.3 ms1.8× faster
median per region39.1 ms / 83.9 ms2.1× faster
UPPER + group31.4 ms / 46.5 ms1.5× faster
|| key + group84.7 ms / 106.1 ms1.3× faster
CASE text + group6.2 ms / 24.5 ms4.0× faster
STRFTIME month + group50.9 ms / 70.4 ms1.4× faster
ILIKE filter30 ms / 54.2 ms1.8× faster
RIGHT JOIN + group29.7 ms / 63.5 ms2.1× faster
FULL JOIN + count19.3 ms / 29.3 ms1.5× faster

Vectro DuckDB · lower is better

In memory · 10M rows

Group-by on 10M rows

count(*) and sum(price * qty) per group, from 2,920 groups to 5.7 million.

4/4

faster or level · count(*) and sum(price * qty) per group, best of 5 · compare/bench-groupby.mjs

account (1M big IDs)36 ms / 88 ms2.4× faster
region + day (2,920 pairs)6 ms / 39 ms6.5× faster
account + region (~5M pairs)50 ms / 139 ms2.8× faster
price (~100K amounts)27 ms / 49 ms1.8× faster

Vectro DuckDB · lower is better

In memory · 10M rows

Joins on 10M orders

The joined table built in full, then counted and summed.

4/4

faster or level · joined table built in full, then counted and summed, best of 5 · compare/bench-join.mjs

orders x 100K customers77 ms / 210 ms2.7× faster
orders x 1M accounts151 ms / 251 ms1.7× faster
left join, half match82 ms / 206 ms2.5× faster
two keys: region + day61 ms / 189 ms3.1× faster

Vectro DuckDB · lower is better

In memory · 10M rows

Distinct counts on 10M rows

Exact distinct counts. The 1M accounts are evenly spaced IDs (1e9 + 7919k); 1M random IDs up to 2^40, with no common step, take 24 ms against DuckDB’s 46.

4/4

faster or level · exact; best of 5 · compare/bench-distinct.mjs

distinct accounts (1M)11 ms / 51 ms4.6× faster
distinct days (365)5 ms / 5 mslevel
distinct accounts per region35 ms / 103 ms2.9× faster
distinct regions per day9 ms / 36 ms4.0× faster

Vectro DuckDB · lower is better

On disk · bigger than memory

A Vectro dataset against a DuckDB database file

The same rows in both, made from whole-number formulas exact in JavaScript and in DuckDB, so the answers can be compared. Each query runs in a fresh process; the first run and the best of 3 are both recorded.

100M rows

QueryVectroDuckDB
scan everything70 ms73 mslevel
filter: EU, qty >= 5100 ms87 ms1.1× slower
the last day (time range)3 ms1 ms3.0× slower
group by region142 ms149 mslevel
top 10 of 1M customers529 ms637 ms1.2× faster
top 10 rows by price15 ms100 ms6.7× faster
join 1M customers126 ms85 ms1.5× slower
distinct customers per region268 ms650 ms2.4× faster
file on disk0.5 GB0.5 GB
peak memory (RSS)344 MB2.9 GB

1 billion rows

QueryVectroDuckDB
scan everything478 ms662 ms1.4× faster
filter: EU, qty >= 5691 ms729 ms1.1× faster
the last day (time range)3 ms4 ms1.3× faster
group by region1.05 s1.25 s1.2× faster
top 10 of 1M customers4.39 s4.50 slevel
top 10 rows by price11 ms843 ms76.6× faster
join 1M customers880 ms627 ms1.4× slower
distinct customers per region2.43 s6.84 s2.8× faster
file on disk5.1 GB5.4 GB
peak memory (RSS)0.37 GB6.9 GB

Where DuckDB is still faster

Every in-memory query above is faster or level. Join 1M customers: 1.5× slower at 100M rows, 1.4× at a billion; filter: EU, qty >= 5: 1.1× slower at 100M; the last day: 3 vs 1 ms at 100M. They are listed as they are.

Run them yourself

cd compare && npm install
node bench-sql.mjs
node bench-groupby.mjs
node bench-join.mjs
node bench-distinct.mjs
ROWS=1000000000 node bench-dataset.mjs

Or race Vectro, DuckDB-WASM and Arquero in this browser on the live page.