mrkeyoor.com_
Sat 31 Oct 07:46 UTC
Dataevaluationupdated 05 Oct 2026

duckdb review

DuckDB is an analytical SQL database that runs inside your application or from a command-line client. It queries CSV, Parquet, and in-process data without making you operate a separate database server, and it can also save data in its own database file.

+151stars / 7d
Verdict

Our api_spec/ install took 31 seconds and 37 MB, but pytest found 0 tests and exited 5, so the clean build is not proof that DuckDB's engine suite passed. DuckDB remains an easy recommendation for local analytical SQL over files or application data when one process can own writes. Choose a server database when independent processes need mature shared writes and central access control.

We ran it

Lab card: what happened when we ran duckdbScreenshot of duckdb (www.duckdb.org)
Install✓ · 31s35 packages · 37 MB
Build✓ · 5s
Tests✗ · 7s0 passed · 0 failed of 0 (pytest)
Known vulns0(pip-audit)
Repo16215 files~1,355,035 lines of source · 257.8 MB · 27 CI workflows · tests dir

Answers from our run

Does duckdb build from source?

Dependencies installed in 31 seconds (35 packages), and the build succeeded in 5 seconds. We cloned commit fc9d6e9 into a clean Debian container with 3 CPUs and no project-specific setup.

Do duckdb's tests pass?

No. The project's own test command finished in 7 seconds and reported 0 passed, 0 failed (pytest).

Does duckdb have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use duckdb?

Services that require several processes to write one native database file: the current concurrency guide keeps read-write work inside one process, while its remote Quack protocol is still beta.

What are the alternatives to duckdb?

SQLite, ClickHouse, Apache DataFusion. Our api_spec/ install took 31 seconds and 37 MB, but pytest found 0 tests and exited 5, so the clean build is not proof that DuckDB's engine suite passed.

Setup4/5Local use is simple; our api_spec test step found 0 tests
Docs5/5Clear SQL, client, extension, build, and concurrency guides
Community5/541,911 stars with October 2026 code and issue activity
Maturity5/5v1.5.6 is active, with a large engine and client ecosystem

Discussed on

  1. hnDuckDB NPM packages 1.3.3 and 1.29.2 compromised with malware395 points
  2. hnDuckDB: SQLite for Analytics290 points
  3. hnDuckDB Ducklake240 points
  4. hnShow HN: Open-source, browser-local data exploration using DuckDB-WASM and PRQL227 points
  5. hnpg_duckdb: Splicing Duck and Elephant DNA186 points

Who it’s for

Analysts who want SQL over local CSV, Parquet, pandas, or R data frames.
Application developers adding analytical queries without deploying a database service.
Data engineers building local transforms, validation jobs, or embedded reporting.
Teams that want the same SQL engine through Python, R, Java, C++, or WebAssembly clients.

Who it’s NOT for

Services that require several processes to write one native database file: the current concurrency guide keeps read-write work inside one process, while its remote Quack protocol is still beta.
Transactional applications dominated by small, competing row updates: DuckDB targets analytical scans and bulk changes, and same-row writes can conflict.
Source contributors expecting a small checkout and one obvious Python test command: our 257.8 MB checkout held about 1,355,035 source lines, while pytest in api_spec/ discovered 0 tests.
Locked-down deployments that assume every feature is already inside the binary: many capabilities arrive as extensions, and autoloading can download an extension on first use.

Setup reality

Our run targeted the Python project in api_spec/ at commit fc9d6e9. Installation succeeded in 31 seconds, adding 35 packages and using 37 MB. The build passed in 5 seconds. Pytest failed with exit 5 after 7 seconds because it found 0 tests: 0 passed and 0 failed. Pip-audit found 0 known vulnerabilities.

Basic local use needs no account, server, or credential. Remote files may need network access and cloud secrets, while extra functions can trigger extension downloads. Building the C++ engine from source is a different path that requires CMake, Python 3, and a C++17 compiler.

Read-write access to a native DuckDB file stays within one process; multiple processes can open it read-only. The repository had 27 CI workflow files and a tests directory, but no Dockerfile. Our successful api_spec/ build does not show that the full C++ engine compiled or passed its own test targets.

DuckDB puts analytical SQL inside the process

DuckDB runs with the application that calls it instead of asking you to maintain a separate server. The CLI and clients for Python, R, Java, and WebAssembly all expose the same analytical engine. A query can place a CSV or Parquet filename directly in the FROM clause. For a notebook, local transformation, or embedded report, that removes an entire service from the path between a file and an answer.

Its SQL goes well beyond a file reader. The README names correlated subqueries, window functions, collations, arrays, structs, and maps. Python can query pandas objects without copying them into a remote database first. You may keep the work transient or persist it to a DuckDB file. Basic local use needs no listening port, database account, or daemon.

The tradeoff is architectural, not cosmetic. DuckDB is built for analytical queries that scan substantial parts of a dataset and for changes made in batches. It is a poor substitute for a transactional web database receiving many small edits from unrelated processes. Used beside that database for analysis, though, it can save a great deal of plumbing.

What happened when we ran it

Our sandbox installed commit fc9d6e9's Python project under api_spec/ in 31 seconds. It added 35 packages and occupied 37 MB. The build completed successfully in another 5 seconds. The Debian container had 3 CPUs, 8 GB of RAM, Python 3.12, no secrets, and no elevated privileges. Pip-audit reported 0 known vulnerabilities in the installed Python dependencies.

The test step failed after 7 seconds with exit code 5. Pytest reported 0 passed and 0 failed out of 0, and the final line said no tests ran in 0.02s. That is a discovery failure, not a green empty suite. The log does not identify a cause, so blaming a missing package, configuration error, or repository defect would go beyond the evidence.

Scope matters here. Our harness selected api_spec/; it did not compile and test the full C++ database engine. The checkout contained 16,215 files, about 1,355,035 source lines, and used 257.8 MB before installation. It also had a tests directory and 27 CI workflow files, although our scan found no Dockerfile. The root README sends engine contributors to make unit and make allunit, neither of which was part of our run.

One process owns native-file writes

DuckDB's current concurrency guide permits one process to open a native database file in read-write mode. That process can use several writer threads, and appends do not conflict. Multiple processes may open the file in read-only mode. When two threads update or delete the same row, optimistic concurrency control can reject the second change, leaving retry behavior to the application.

This boundary is easy to miss because embedding feels frictionless. A Python worker, a web process, and a scheduled job cannot all assume they may write the same file independently. The docs now describe Quack for multiple-process writes, but label it beta as of DuckDB 1.5.2. For a stable shared-write design, the same page points readers toward DuckLake with a PostgreSQL catalog.

That does not make DuckDB fragile. It makes the ownership model explicit. If one application process owns writes and threads do the work, the design fits. If separate machines need accounts, authorization, backups, and concurrent writes behind a network endpoint, start with a server database rather than building those controls around an embedded file.

Extensions can download code on first use

DuckDB keeps part of its feature set in extensions. Parquet, JSON, time zones, HTTP and S3 access, spatial functions, and other capabilities use that mechanism. Installable extensions are downloaded, checked, and stored in a local directory. Several core extensions autoload, so a query that reaches an HTTPS resource can cause httpfs to be installed without a separate INSTALL statement.

That is friendly on a laptop and important in a sealed container. A production image may need extension binaries packaged before deployment, a writable extension directory, and cloud credentials for remote objects. Pinning only the language package leaves those runtime pieces outside the record. Test the exact DuckDB release, extension set, file formats, and endpoints you will run.

The repository itself has no root Dockerfile according to our scan, which is reasonable for an embeddable database but removes a canonical source-development container. The README's native build path calls for CMake, Python 3, and a C++17 compiler. Those requirements belong to engine contributors. Someone who only needs the released Python package or CLI should not treat our 257.8 MB source checkout as the normal installation experience.

October activity and v1.5.6 show active maintenance

GitHub showed 41,911 stars and 978 open issues and pull requests, not 978 confirmed bugs. The repository was pushed on October 4, 2026, and recently updated issues and pull requests were still moving on October 5. Release v1.5.6 shipped on September 28 with fixes across query planning, storage, Parquet, extensions, the C API, and concurrency. The release and issue dates support a high community score.

A large active queue also means upgrades deserve real regression queries. The v1.5.6 notes include fixes for wrong results, crashes, write-ahead-log recovery, time zones, and extension updates. That breadth is normal for a database used through many clients and file formats, but it argues against casual version bumps. Keep representative SQL and data files in your own tests.

DuckDB earns its place when the job is analytical and the process boundary is acceptable. Our run verified a 31-second Python install and a 5-second build inside api_spec/; it also exposed a test command that found nothing. Take both facts seriously: trying DuckDB is easy, while proving your chosen client, extensions, files, and concurrency pattern still belongs to you.

Alternatives

ProjectWhat it isPick it when
SQLiteAn embedded SQL database centered on application storage and transactions.pick this instead when small row-level transactions matter more than analytical scans.
ClickHouse gh↗A server database for real-time analytical workloads and remote clients.pick this instead when many users or services need a shared analytics server.
Apache DataFusion gh↗A Rust SQL query engine built around Apache Arrow.pick this instead when you want a Rust query engine to assemble and extend yourself.
Polars gh↗A Rust and Python DataFrame query engine with a fluent expression API.pick this instead when DataFrame expressions are your main interface and SQL is secondary.

Sources

  1. DuckDB README
  2. Why DuckDB
  3. DuckDB concurrency documentation
  4. DuckDB extension documentation
  5. DuckDB v1.5.6 release
  6. Measured DuckDB commit fc9d6e9

More data reviews

jq · pgx · HowToLiveLonger · ip2region · dbdelve · litestream · the whole board →