The better-duck workspace ships a benchmark harness that measuresDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nimdeveloper/better-duck/llms.txt
Use this file to discover all available pages before exploring further.
better-duck-core head-to-head against the community duckdb crate. Because both crates vendor their own copy of DuckDB (and each sets links = "duckdb", preventing them from being linked into a single binary), each side runs as its own process — but both are in-process native calls with no per-operation subprocess overhead, so the timings are directly comparable. The harness covers three benchmark groups: primitive types, composite types, and five representative operations.
The benchmark harness lives in
crates/better-duck-core/benches/. The full tables, raw JSON numbers, and SVG charts are generated in docs/benchmarks/ when you run the comparison command.Running Benchmarks
docs/benchmarks/:
REPORT.md— full tables and embedded SVG chartsresults.json— raw latency and throughput numberscomparison-primitive-types-latency.svg/comparison-primitive-types-throughput.svgcomparison-composite-types-latency.svg/comparison-composite-types-throughput.svgcomparison-operations-latency.svg/comparison-operations-throughput.svg
Operations Group Results
The operations group covers five representative end-to-end workloads. Numbers below are sample results from a single run; seeREPORT.md for the full primitive-type and composite-type tables.
| Workload | better-duck-core | duckdb crate |
|---|---|---|
| CRUD basics (4 ops) | 4.73 ms / 846 ops/s | 4.59 ms / 871 ops/s |
| Bulk ingest — 10k rows (appender) | 31.94 ms / 313.1 k rows/s | 38.55 ms / 259.4 k rows/s |
| Analytical GROUP BY — 100k rows | 4.19 ms / 23.9 M rows/s | 4.24 ms / 23.6 M rows/s |
| Prepared reuse — 100 queries | 75.72 ms / 1.3 k queries/s | 68.16 ms / 1.5 k queries/s |
| All-types scan — 1k rows, 11 cols | 32.91 ms / 30.4 k rows/s | 27.46 ms / 36.4 k rows/s |
- CRUD basics — a single-row
INSERT, a pointSELECT, anUPDATE, and aDELETEin sequence. - Bulk ingest — ingesting 10,000 rows through each library’s native appender API.
- Analytical GROUP BY — a
GROUP BY + AVG + ORDER BYover a pre-populated 100,000-row table (query execution time only; table setup is excluded). - Prepared reuse — 100 point-
SELECTqueries reusing one prepared statement (aCachedStatementon the better-duck side). - All-types scan — inserting and reading back 1,000 rows across 11 mixed column types in a single table.
Benchmark Groups
The harness runs three benchmark groups, each producing a latency SVG and a throughput SVG:Primitive types
Insert + full-scan of 20,000 rows for each scalar DuckDB type:
BOOLEAN, TINYINT–HUGEINT, UTINYINT–UHUGEINT, FLOAT, DOUBLE, VARCHAR, DECIMAL(18,4), DATE, TIME, TIMESTAMP, INTERVAL, TIMESTAMPTZ, BLOB, UUID.Composite types
Insert + full-scan of 2,000 rows for
LIST, ARRAY, STRUCT, and MAP columns. The duckdb crate has no safe write API for these types; those rows use a neutral placeholder so that the chart shape is not distorted.Operations
Five representative end-to-end workloads as described in the table above. This is the group most relevant for assessing real-world query-path performance.
Interpreting Results
Numbers vary between runs due to normal system noise — OS scheduling, CPU thermal state, and background activity all affect wall-clock latency. The relative comparison within a single run is what is meaningful; do not compare absolute millisecond figures across runs on different machines or different days. A few observations from the sample results above:- Bulk ingest: better-duck-core is ~17% faster on the appender path (31.9 ms vs 38.6 ms). This reflects the direct
duckdb_append_*typed paths throughout. - Analytical queries: both libraries are essentially equivalent (~4.2 ms), which is expected — DuckDB’s query engine does the work and both libraries call the same underlying execution path.
- Prepared reuse: better-duck-core is ~10% slower on prepared-statement round-trips. This is an area of active focus (see the changelog for recent fixes).
- All-types scan: better-duck-core is moderately slower on mixed-type scans, reflecting per-type dispatch overhead in the read path.