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
d89ef84 · 2026-11-01
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 filter3.4 ms / 10.1 ms3.0× faster
group by region7.8 ms / 30.7 ms3.9× faster
join + filter + group17.3 ms / 29 ms1.7× faster
top 10 customers12.9 ms / 42.5 ms3.3× faster
distinct customers per month30.8 ms / 70.6 ms2.3× faster
top 20 rows by price8.2 ms / 22.3 ms2.7× faster
CASE inside SUM7.6 ms / 35.2 ms4.6× faster
IN (subquery)19.7 ms / 25.2 ms1.3× faster
correlated subquery16 ms / 50.6 ms3.2× faster
top 3 per region (RANK)35.9 ms / 118.6 ms3.3× faster
ROW_NUMBER over all rows123.8 ms / 178.7 ms1.4× faster
running total by day8.6 ms / 14.6 ms1.7× faster
median per region33.6 ms / 71.7 ms2.1× faster
UPPER + group31.4 ms / 40 ms1.3× faster
|| key + group84.2 ms / 93.8 ms1.1× faster
CASE text + group5.3 ms / 20.7 ms3.9× faster
STRFTIME month + group47.2 ms / 63.1 ms1.3× faster
ILIKE filter29.2 ms / 45.6 ms1.6× faster
RIGHT JOIN + group27.2 ms / 53.8 ms2.0× faster
FULL JOIN + count16.9 ms / 25.5 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)29 ms / 61 ms2.1× faster
region + day (2,920 pairs)8 ms / 34 ms4.3× faster
account + region (~5M pairs)42 ms / 115 ms2.7× faster
price (~100K amounts)23 ms / 42 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 customers64 ms / 163 ms2.5× faster
orders x 1M accounts113 ms / 200 ms1.8× faster
left join, half match74 ms / 170 ms2.3× faster
two keys: region + day57 ms / 152 ms2.7× 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)9 ms / 44 ms4.9× faster
distinct days (365)4 ms / 4 mslevel
distinct accounts per region30 ms / 85 ms2.8× faster
distinct regions per day7 ms / 31 ms4.4× 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 everything49 ms61 ms1.2× faster
filter: EU, qty >= 570 ms72 mslevel
the last day (time range)3 ms1 ms3.0× slower
group by region114 ms124 ms1.1× faster
top 10 of 1M customers460 ms487 ms1.1× faster
top 10 rows by price10 ms87 ms8.7× faster
join 1M customers84 ms68 ms1.2× slower
distinct customers per region247 ms517 ms2.1× faster
file on disk0.5 GB0.5 GB
peak memory (RSS)343 MB3.1 GB

1 billion rows

QueryVectroDuckDB
scan everything460 ms648 ms1.4× faster
filter: EU, qty >= 5665 ms723 ms1.1× faster
the last day (time range)3 ms5 ms1.7× faster
group by region1.13 s1.24 s1.1× faster
top 10 of 1M customers4.46 s4.62 slevel
top 10 rows by price11 ms827 ms75.2× faster
join 1M customers745 ms587 ms1.3× slower
distinct customers per region2.45 s6.50 s2.7× faster
file on disk5.1 GB5.4 GB
peak memory (RSS)0.37 GB6.6 GB

Where DuckDB is still faster

A join over a file with a GROUP BY on the joined table's columns: 1.2× slower at 100M rows and 1.3× at a billion. And single-chunk lookups like "the last day" take a millisecond or two more than DuckDB's at 100M rows. Both 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.