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
| Query | csvlite | DuckDB | Bars | vs DuckDB |
|---|---|---|---|---|
| Text matchregion = north | 10 ms | 54 ms | 5.4× faster | |
| Regex searchdescription has the word café | 14 ms | 58 ms | 4.0× faster | |
| Number rangeamount 25,000–75,000 | 10 ms | 56 ms | 5.9× faster | |
| Date rangeoccurred_at in a range | 10 ms | 56 ms | 5.9× faster | |
| Sort textevery row by region | 10 ms | 61 ms | 6.4× faster | |
| Sort numbersevery row by amount | 10 ms | 64 ms | 6.6× faster | |
| Sort datesevery row by occurred_at | 12 ms | 65 ms | 5.4× faster | |
| Group + sumcount, sum(amount) by region, status | 12 ms | 64 ms | 5.3× faster | |
| Group + distinct…plus distinct descriptions | 12 ms | 69 ms | 5.6× faster |
Chart data
| After | csvlite | DuckDB | DuckDB, table first |
|---|---|---|---|
| Open | 10 ms | 0.0 ms | 105 ms |
| Text match | 12 ms | 54 ms | 106 ms |
| Regex search | 18 ms | 112 ms | 114 ms |
| Number range | 20 ms | 169 ms | 117 ms |
| Date range | 23 ms | 225 ms | 120 ms |
| Sort text | 25 ms | 286 ms | 126 ms |
| Sort numbers | 27 ms | 350 ms | 133 ms |
| Sort dates | 30 ms | 415 ms | 141 ms |
| Group + sum | 34 ms | 479 ms | 150 ms |
| Group + distinct | 40 ms | 548 ms | 162 ms |
100 MB
532,923 rows · 15 columns · File in page cache
| Query | csvlite | DuckDB | Bars | vs DuckDB |
|---|---|---|---|---|
| Text matchregion = north | 15 ms | 85 ms | 5.8× faster | |
| Regex searchdescription has the word café | 32 ms | 96 ms | 3.0× faster | |
| Number rangeamount 25,000–75,000 | 21 ms | 88 ms | 4.2× faster | |
| Date rangeoccurred_at in a range | 19 ms | 89 ms | 4.7× faster | |
| Sort textevery row by region | 29 ms | 268 ms | 9.2× faster | |
| Sort numbersevery row by amount | 26 ms | 286 ms | 10.9× faster | |
| Sort datesevery row by occurred_at | 27 ms | 274 ms | 10.3× faster | |
| Group + sumcount, sum(amount) by region, status | 29 ms | 97 ms | 3.3× faster | |
| Group + distinct…plus distinct descriptions | 39 ms | 108 ms | 2.8× faster |
Chart data
| After | csvlite | DuckDB | DuckDB, table first |
|---|---|---|---|
| Open | 11 ms | 0.0 ms | 393 ms |
| Text match | 14 ms | 85 ms | 395 ms |
| Regex search | 35 ms | 180 ms | 416 ms |
| Number range | 45 ms | 269 ms | 424 ms |
| Date range | 53 ms | 358 ms | 435 ms |
| Sort text | 69 ms | 625 ms | 456 ms |
| Sort numbers | 83 ms | 911 ms | 482 ms |
| Sort dates | 97 ms | 1.2 s | 500 ms |
| Group + sum | 114 ms | 1.3 s | 516 ms |
| Group + distinct | 140 ms | 1.4 s | 547 ms |
1 GB
5,300,205 rows · 15 columns · File in page cache
| Query | csvlite | DuckDB | Bars | vs DuckDB |
|---|---|---|---|---|
| Text matchregion = north | 90 ms | 409 ms | 4.5× faster | |
| Regex searchdescription has the word café | 264 ms | 475 ms | 1.8× faster | |
| Number rangeamount 25,000–75,000 | 172 ms | 408 ms | 2.4× faster | |
| Date rangeoccurred_at in a range | 139 ms | 395 ms | 2.8× faster | |
| Sort textevery row by region | 226 ms | 2.4 s | 10.8× faster | |
| Sort numbersevery row by amount | 197 ms | 2.4 s | 12.1× faster | |
| Sort datesevery row by occurred_at | 191 ms | 2.3 s | 12.3× faster | |
| Group + sumcount, sum(amount) by region, status | 236 ms | 439 ms | 1.9× faster | |
| Group + distinct…plus distinct descriptions | 362 ms | 563 ms | 1.6× faster |
Chart data
| After | csvlite | DuckDB | DuckDB, table first |
|---|---|---|---|
| Open | 69 ms | 0.0 ms | 2.4 s |
| Text match | 99 ms | 409 ms | 2.4 s |
| Regex search | 303 ms | 884 ms | 2.5 s |
| Number range | 413 ms | 1.3 s | 2.6 s |
| Date range | 491 ms | 1.7 s | 2.6 s |
| Sort text | 654 ms | 4.1 s | 2.7 s |
| Sort numbers | 791 ms | 6.5 s | 2.9 s |
| Sort dates | 920 ms | 8.9 s | 3.0 s |
| Group + sum | 1.1 s | 9.3 s | 3.0 s |
| Group + distinct | 1.4 s | 9.9 s | 3.1 s |
10 GB
53,002,050 rows · 15 columns · Cold cache: evicted from memory before every run
| Query | csvlite | DuckDB | Bars | vs DuckDB |
|---|---|---|---|---|
| Text matchregion = north | 4.6 s | 4.1 s | 1.1× slower | |
| Regex searchdescription has the word café | 6.2 s | 5.1 s | 1.2× slower | |
| Number rangeamount 25,000–75,000 | 5.3 s | 4.4 s | 1.2× slower | |
| Date rangeoccurred_at in a range | 5.0 s | 4.7 s | on par | |
| Sort textevery row by region | 9.1 s | 29 s | 3.1× faster | |
| Sort numbersevery row by amount | 6.4 s | 28 s | 4.3× faster | |
| Sort datesevery row by occurred_at | 6.3 s | 26 s | 4.1× faster | |
| Group + sumcount, sum(amount) by region, status | 5.7 s | 4.7 s | 1.2× slower | |
| Group + distinct…plus distinct descriptions | 7.2 s | 5.8 s | 1.3× slower |
Chart data
| After | csvlite | DuckDB | DuckDB, table first |
|---|---|---|---|
| Open | 3.1 s | 0.0 ms | 28 s |
| Text match | 4.7 s | 4.1 s | 28 s |
| Regex search | 7.8 s | 9.2 s | 30 s |
| Number range | 9.9 s | 14 s | 30 s |
| Date range | 12 s | 18 s | 31 s |
| Sort text | 18 s | 47 s | 35 s |
| Sort numbers | 21 s | 75 s | 39 s |
| Sort dates | 24 s | 101 s | 43 s |
| Group + sum | 27 s | 105 s | 45 s |
| Group + distinct | 31 s | 111 s | 47 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 LASTcsvliteClick 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, statuscsvlitePivot · 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
All four tools · vs pandas · vs Polars