csvlite vs DuckDB · measured 29 September 2026

Faster than DuckDB.
Without writing SQL.

Same files, same laptop, CSV to answer. Median of 5 runs.

typical4.3× fastermedian of 36 measured queries
best case12.3× fasterSort dates, 1 GB
1 GB1.6–12.3×faster on every query
10 GB · 9 queries31 svs 111 s in DuckDB

Every query

10 MB

53,596 rows · 15 columns · File in page cache

10 MB: median time from CSV to answer
QuerycsvliteDuckDBBarsvs DuckDB
Text matchregion = north10 ms54 ms5.4× faster
Regex searchdescription has the word café14 ms58 ms4.0× faster
Number rangeamount 25,000–75,00010 ms56 ms5.9× faster
Date rangeoccurred_at in a range10 ms56 ms5.9× faster
Sort textevery row by region10 ms61 ms6.4× faster
Sort numbersevery row by amount10 ms64 ms6.6× faster
Sort datesevery row by occurred_at12 ms65 ms5.4× faster
Group + sumcount, sum(amount) by region, status12 ms64 ms5.3× faster
Group + distinct…plus distinct descriptions12 ms69 ms5.6× faster
Open once, keep askingTotal time as queries pile up. DuckDB re-reads the CSV per query; grey loads it into DuckDB first.
Total time after 9 queries, 10 MB: csvlite 40 ms, DuckDB 548 ms, DuckDB, table first 162 ms0 ms200 ms400 ms600 msopen123456789queries answered548 msDuckDB162 msDuckDB, table first40 mscsvlite
Chart data
AftercsvliteDuckDBDuckDB, table first
Open10 ms0.0 ms105 ms
Text match12 ms54 ms106 ms
Regex search18 ms112 ms114 ms
Number range20 ms169 ms117 ms
Date range23 ms225 ms120 ms
Sort text25 ms286 ms126 ms
Sort numbers27 ms350 ms133 ms
Sort dates30 ms415 ms141 ms
Group + sum34 ms479 ms150 ms
Group + distinct40 ms548 ms162 ms

100 MB

532,923 rows · 15 columns · File in page cache

100 MB: median time from CSV to answer
QuerycsvliteDuckDBBarsvs DuckDB
Text matchregion = north15 ms85 ms5.8× faster
Regex searchdescription has the word café32 ms96 ms3.0× faster
Number rangeamount 25,000–75,00021 ms88 ms4.2× faster
Date rangeoccurred_at in a range19 ms89 ms4.7× faster
Sort textevery row by region29 ms268 ms9.2× faster
Sort numbersevery row by amount26 ms286 ms10.9× faster
Sort datesevery row by occurred_at27 ms274 ms10.3× faster
Group + sumcount, sum(amount) by region, status29 ms97 ms3.3× faster
Group + distinct…plus distinct descriptions39 ms108 ms2.8× faster
Open once, keep askingTotal time as queries pile up. DuckDB re-reads the CSV per query; grey loads it into DuckDB first.
Total time after 9 queries, 100 MB: csvlite 140 ms, DuckDB 1.4 s, DuckDB, table first 547 ms0 s0.5 s1 s1.5 sopen123456789queries answered1.4 sDuckDB547 msDuckDB, table first140 mscsvlite
Chart data
AftercsvliteDuckDBDuckDB, table first
Open11 ms0.0 ms393 ms
Text match14 ms85 ms395 ms
Regex search35 ms180 ms416 ms
Number range45 ms269 ms424 ms
Date range53 ms358 ms435 ms
Sort text69 ms625 ms456 ms
Sort numbers83 ms911 ms482 ms
Sort dates97 ms1.2 s500 ms
Group + sum114 ms1.3 s516 ms
Group + distinct140 ms1.4 s547 ms

1 GB

5,300,205 rows · 15 columns · File in page cache

1 GB: median time from CSV to answer
QuerycsvliteDuckDBBarsvs DuckDB
Text matchregion = north90 ms409 ms4.5× faster
Regex searchdescription has the word café264 ms475 ms1.8× faster
Number rangeamount 25,000–75,000172 ms408 ms2.4× faster
Date rangeoccurred_at in a range139 ms395 ms2.8× faster
Sort textevery row by region226 ms2.4 s10.8× faster
Sort numbersevery row by amount197 ms2.4 s12.1× faster
Sort datesevery row by occurred_at191 ms2.3 s12.3× faster
Group + sumcount, sum(amount) by region, status236 ms439 ms1.9× faster
Group + distinct…plus distinct descriptions362 ms563 ms1.6× faster
Open once, keep askingTotal time as queries pile up. DuckDB re-reads the CSV per query; grey loads it into DuckDB first.
Total time after 9 queries, 1 GB: csvlite 1.4 s, DuckDB 9.9 s, DuckDB, table first 3.1 s0 s2.5 s5 s7.5 s10 sopen123456789queries answered9.9 sDuckDB3.1 sDuckDB, table first1.4 scsvlite
Chart data
AftercsvliteDuckDBDuckDB, table first
Open69 ms0.0 ms2.4 s
Text match99 ms409 ms2.4 s
Regex search303 ms884 ms2.5 s
Number range413 ms1.3 s2.6 s
Date range491 ms1.7 s2.6 s
Sort text654 ms4.1 s2.7 s
Sort numbers791 ms6.5 s2.9 s
Sort dates920 ms8.9 s3.0 s
Group + sum1.1 s9.3 s3.0 s
Group + distinct1.4 s9.9 s3.1 s

10 GB

53,002,050 rows · 15 columns · Cold cache: evicted from memory before every run

10 GB: median time from CSV to answer
QuerycsvliteDuckDBBarsvs DuckDB
Text matchregion = north4.6 s4.1 s1.1× slower
Regex searchdescription has the word café6.2 s5.1 s1.2× slower
Number rangeamount 25,000–75,0005.3 s4.4 s1.2× slower
Date rangeoccurred_at in a range5.0 s4.7 son par
Sort textevery row by region9.1 s29 s3.1× faster
Sort numbersevery row by amount6.4 s28 s4.3× faster
Sort datesevery row by occurred_at6.3 s26 s4.1× faster
Group + sumcount, sum(amount) by region, status5.7 s4.7 s1.2× slower
Group + distinct…plus distinct descriptions7.2 s5.8 s1.3× slower
Open once, keep askingTotal time as queries pile up. DuckDB re-reads the CSV per query; grey loads it into DuckDB first.
Total time after 9 queries, 10 GB: csvlite 31 s, DuckDB 111 s, DuckDB, table first 47 s0 s50 s100 s150 sopen123456789queries answered111 sDuckDB47 sDuckDB, table first31 scsvlite
Chart data
AftercsvliteDuckDBDuckDB, table first
Open3.1 s0.0 ms28 s
Text match4.7 s4.1 s28 s
Regex search7.8 s9.2 s30 s
Number range9.9 s14 s30 s
Date range12 s18 s31 s
Sort text18 s47 s35 s
Sort numbers21 s75 s39 s
Sort dates24 s101 s43 s
Group + sum27 s105 s45 s
Group + distinct31 s111 s47 s

The code you’d write

As benchmarked

Text matchcsvlite 90 msDuckDB 409 msat 1 GB
SELECT count(*)
FROM read_csv('data.csv', all_varchar = true)
WHERE region = 'north'
csvliteAdd filter · region = north
Sort numberscsvlite 197 msDuckDB 2.4 sat 1 GB
SELECT row_number() OVER () - 1 AS idx
FROM read_csv('data.csv', all_varchar = true)
ORDER BY try_cast(amount AS DOUBLE) NULLS LAST
csvliteClick the amount header
Group + sumcsvlite 236 msDuckDB 439 msat 1 GB
SELECT region, status,
       count(*), sum(try_cast(amount AS DOUBLE))
FROM read_csv('data.csv', all_varchar = true)
GROUP BY region, status
csvlitePivot · region, status · Sum of amount
Machine
Intel Core i7-11850H · 32 GB RAM · NVMe SSD · Linux. Every run capped at 8 GB of memory.
Versions
csvlite 1.0.0 · DuckDB 1.5.5 · Polars 1.44.2 · pandas 3.0.6. All columns read as text.
Timing
CSV to answer, fresh process per run, startup excluded. ≤1 GB warm; 10 GB cold. Out of memory: one capped attempt. DuckDB, table first: the same queries after loading the CSV into DuckDB, a separate five-run cohort.
Data
Generated analytics CSV. All 1064 raw runs (plus load-first) · csvlite-only benchmarks

Try it on your own CSV

Download csvlite