csvlite vs pandas, Polars & DuckDB · measured 29 September 2026
No code.
Faster than code.
Same files, same laptop, CSV to answer. Median of 5 runs.
vs DuckDB4.3× fastertypical · up to 12.3×
vs Polars2.2× fastertypical · up to 5.6× · out of memory at 10 GB
vs pandas57.3× fastertypical · up to 162× · out of memory at 10 GB
10 GB · 9 queries31 svs 111 s in DuckDB, the next fastest
Every query, every size
One dot per query and file size
The numbers
10 MB
53,596 rows · 15 columns · File in page cache
| Query | csvlite | DuckDB | Polars | pandas | vs fastest other |
|---|---|---|---|---|---|
| Text matchregion = north | 10 ms | 54 ms | 19 ms | 156 ms | 1.9× faster |
| Regex searchdescription has the word café | 14 ms | 58 ms | 21 ms | 190 ms | 1.4× faster |
| Number rangeamount 25,000–75,000 | 10 ms | 56 ms | 18 ms | 157 ms | 1.9× faster |
| Date rangeoccurred_at in a range | 10 ms | 56 ms | 21 ms | 151 ms | 2.2× faster |
| Sort textevery row by region | 10 ms | 61 ms | 21 ms | 166 ms | 2.2× faster |
| Sort numbersevery row by amount | 10 ms | 64 ms | 20 ms | 162 ms | 2.0× faster |
| Sort datesevery row by occurred_at | 12 ms | 65 ms | 23 ms | 153 ms | 1.9× faster |
| Group + sumcount, sum(amount) by region, status | 12 ms | 64 ms | 20 ms | 167 ms | 1.7× faster |
| Group + distinct…plus distinct descriptions | 12 ms | 69 ms | 22 ms | 181 ms | 1.8× faster |
Chart data
| After | csvlite | DuckDB | Polars | pandas |
|---|---|---|---|---|
| Open | 10 ms | 0.0 ms | 0.0 ms | 148 ms |
| Text match | 12 ms | 54 ms | 19 ms | 151 ms |
| Regex search | 18 ms | 112 ms | 39 ms | 185 ms |
| Number range | 20 ms | 169 ms | 57 ms | 198 ms |
| Date range | 23 ms | 225 ms | 78 ms | 204 ms |
| Sort text | 25 ms | 286 ms | 99 ms | 222 ms |
| Sort numbers | 27 ms | 350 ms | 119 ms | 236 ms |
| Sort dates | 30 ms | 415 ms | 142 ms | 244 ms |
| Group + sum | 34 ms | 479 ms | 162 ms | 266 ms |
| Group + distinct | 40 ms | 548 ms | 184 ms | 296 ms |
100 MB
532,923 rows · 15 columns · File in page cache
| Query | csvlite | DuckDB | Polars | pandas | vs fastest other |
|---|---|---|---|---|---|
| Text matchregion = north | 15 ms | 85 ms | 64 ms | 1.4 s | 4.4× faster |
| Regex searchdescription has the word café | 32 ms | 96 ms | 88 ms | 1.7 s | 2.7× faster |
| Number rangeamount 25,000–75,000 | 21 ms | 88 ms | 79 ms | 1.6 s | 3.8× faster |
| Date rangeoccurred_at in a range | 19 ms | 89 ms | 90 ms | 1.5 s | 4.7× faster |
| Sort textevery row by region | 29 ms | 268 ms | 80 ms | 1.7 s | 2.7× faster |
| Sort numbersevery row by amount | 26 ms | 286 ms | 76 ms | 1.6 s | 2.9× faster |
| Sort datesevery row by occurred_at | 27 ms | 274 ms | 90 ms | 1.6 s | 3.4× faster |
| Group + sumcount, sum(amount) by region, status | 29 ms | 97 ms | 86 ms | 1.7 s | 3.0× faster |
| Group + distinct…plus distinct descriptions | 39 ms | 108 ms | 95 ms | 1.7 s | 2.5× faster |
Chart data
| After | csvlite | DuckDB | Polars | pandas |
|---|---|---|---|---|
| Open | 11 ms | 0.0 ms | 0.0 ms | 1.5 s |
| Text match | 14 ms | 85 ms | 64 ms | 1.5 s |
| Regex search | 35 ms | 180 ms | 152 ms | 1.8 s |
| Number range | 45 ms | 269 ms | 230 ms | 2.0 s |
| Date range | 53 ms | 358 ms | 320 ms | 2.0 s |
| Sort text | 69 ms | 625 ms | 400 ms | 2.2 s |
| Sort numbers | 83 ms | 911 ms | 475 ms | 2.4 s |
| Sort dates | 97 ms | 1.2 s | 565 ms | 2.5 s |
| Group + sum | 114 ms | 1.3 s | 651 ms | 2.7 s |
| Group + distinct | 140 ms | 1.4 s | 746 ms | 2.9 s |
1 GB
5,300,205 rows · 15 columns · File in page cache
| Query | csvlite | DuckDB | Polars | pandas | vs fastest other |
|---|---|---|---|---|---|
| Text matchregion = north | 90 ms | 409 ms | 376 ms | 15 s | 4.2× faster |
| Regex searchdescription has the word café | 264 ms | 475 ms | 613 ms | 17 s | 1.8× faster |
| Number rangeamount 25,000–75,000 | 172 ms | 408 ms | 473 ms | 16 s | 2.4× faster |
| Date rangeoccurred_at in a range | 139 ms | 395 ms | 779 ms | 15 s | 2.8× faster |
| Sort textevery row by region | 226 ms | 2.4 s | 535 ms | 17 s | 2.4× faster |
| Sort numbersevery row by amount | 197 ms | 2.4 s | 551 ms | 16 s | 2.8× faster |
| Sort datesevery row by occurred_at | 191 ms | 2.3 s | 766 ms | 15 s | 4.0× faster |
| Group + sumcount, sum(amount) by region, status | 236 ms | 439 ms | 620 ms | 16 s | 1.9× faster |
| Group + distinct…plus distinct descriptions | 362 ms | 563 ms | 716 ms | 18 s | 1.6× faster |
Chart data
| After | csvlite | DuckDB | Polars | pandas |
|---|---|---|---|---|
| Open | 69 ms | 0.0 ms | 0.0 ms | 14 s |
| Text match | 99 ms | 409 ms | 376 ms | 14 s |
| Regex search | 303 ms | 884 ms | 989 ms | 18 s |
| Number range | 413 ms | 1.3 s | 1.5 s | 19 s |
| Date range | 491 ms | 1.7 s | 2.2 s | 20 s |
| Sort text | 654 ms | 4.1 s | 2.8 s | 22 s |
| Sort numbers | 791 ms | 6.5 s | 3.3 s | 24 s |
| Sort dates | 920 ms | 8.9 s | 4.1 s | 25 s |
| Group + sum | 1.1 s | 9.3 s | 4.7 s | 26 s |
| Group + distinct | 1.4 s | 9.9 s | 5.4 s | 29 s |
10 GB
53,002,050 rows · 15 columns · Cold cache: evicted from memory before every run
| Query | csvlite | DuckDB | Polars | pandas | vs fastest other |
|---|---|---|---|---|---|
| Text matchregion = north | 4.6 s | 4.1 s | 7.6 s | out of memory | 1.1× slower |
| Regex searchdescription has the word café | 6.2 s | 5.1 s | 10 s | out of memory | 1.2× slower |
| Number rangeamount 25,000–75,000 | 5.3 s | 4.4 s | 8.6 s | out of memory | 1.2× slower |
| Date rangeoccurred_at in a range | 5.0 s | 4.7 s | 8.7 s | out of memory | on par |
| Sort textevery row by region | 9.1 s | 29 s | 9.9 s | out of memory | on par |
| Sort numbersevery row by amount | 6.4 s | 28 s | 9.7 s | out of memory | 1.5× faster |
| Sort datesevery row by occurred_at | 6.3 s | 26 s | 9.1 s | out of memory | 1.4× faster |
| Group + sumcount, sum(amount) by region, status | 5.7 s | 4.7 s | 11 sout of memory in 1 of 5 runs | out of memory | 1.2× slower |
| Group + distinct…plus distinct descriptions | 7.2 s | 5.8 s | out of memory | out of memory | 1.3× slower |
Chart data
| After | csvlite | DuckDB | Polars | pandas |
|---|---|---|---|---|
| Open | 3.1 s | 0.0 ms | — | — |
| Text match | 4.7 s | 4.1 s | — | — |
| Regex search | 7.8 s | 9.2 s | — | — |
| Number range | 9.9 s | 14 s | — | — |
| Date range | 12 s | 18 s | — | — |
| Sort text | 18 s | 47 s | — | — |
| Sort numbers | 21 s | 75 s | — | — |
| Sort dates | 24 s | 101 s | — | — |
| Group + sum | 27 s | 105 s | — | — |
| Group + distinct | 31 s | 111 s | — | — |
Head to head
- 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.
- Data
- Generated analytics CSV. All 1064 raw runs (plus load-first) · csvlite-only benchmarks