DuckDB's README has no install command, and its Makefile has a sqlite target
GitHub describes it as DuckDB is an analytical in-process SQL database management system. The repository metadata lists C++ as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- DuckDB is an in-process analytical SQL database written in C++, with clients for the CLI, Python, R, Java and Wasm. The file is written for contributors: installation is a single sentence pointing at a docs page, while the development section spells out CMake, Python 3, a C++17 compiler and six make targets. The Makefile is where the unstated assumptions live.
- Who is it for?
- Reach for DuckDB when your workload is analytical, when the data is sitting in CSV or Parquet files, and when you want a SQL dialect with nested correlated subqueries, window functions, collations and array, struct and map types without standing up a server.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Installation section is one sentence and one URL
Here is the whole of it: if you want to install DuckDB, please see the installation page at https://duckdb.org/docs/installation/ for instructions. No command, no platform list, no package name, no version, so the answer to where to get DuckDB is that page and nothing in this repository.
That is not an oversight so much as a division of labour. Everything else in the file that is concrete serves someone building DuckDB rather than someone running it. The development section names CMake, Python 3 and a C++17 compliant compiler, then gives you the compile step, a debug variant, two test targets, and a benchmark route. The user-facing half of the documentation is, by contrast, a set of links to duckdb.org.
First use is the one place the file hands you something runnable, and it is a single statement, the import example, where a CSV or Parquet file is referenced directly in the FROM clause:
SELECT * FROM 'myfile.csv';
SELECT * FROM 'myfile.parquet';No schema, no CREATE TABLE, no connection string. Read the file, get rows. Everything after that, including which client to use, is a link.
make sqlite is a declared target and SQLite is never named in the README
The .PHONY line at the top of the Makefile is worth reading as a list of intentions: all, opt, unit, clean, debug, release, test, unittest, allunit, benchmark, docs, doxygen, format, sqlite, smoke, runnertests, sync_out_of_tree_extensions.
`sqlite` sits in the middle of that list. The README does not mention SQLite once, in any section, in any form. So the repository contains a target whose purpose a user reading the documentation cannot infer, and a user asking how DuckDB relates to SQLite, which is one of the most common questions aimed at it, gets nothing from this file at all.
The same silence covers every other comparison. The questions directed at this project are almost entirely of the form DuckDB versus something else, versus SQLite, versus PostgreSQL, versus ClickHouse, versus Polars. The file takes no position on any of them, and offers no migration note, no compatibility matrix and no statement about what it is not.
The consequence is that the entire comparison-shopping step happens away from the project, which is fine as long as you know it is happening. What the file does give you is the benchmark route, and that is the honest place to settle a speed question yourself.
Build parallelism is a percentage of your core count, with no upper bound
The Makefile does not take a job count as an option. It derives one. It detects the CPU count with `nproc`, falls back to `sysctl -n hw.ncpu`, falls back again to the `NUMBER_OF_PROCESSORS` environment variable, and if all three fail it prints 1.
From that number it computes two values. `CI_BUILD_JOBS` takes 80 percent of the CPU count, and clamps only at the bottom, so anything under 1.25 cores rounds up to a single job. `CI_TIDY_JOBS` takes 50 percent. The build value is exported as `CMAKE_BUILD_PARALLEL_LEVEL` unless that variable is already set in your environment, in which case the Makefile leaves it alone.
So the ceiling is your machine and the floor is serial, and there is no cap at the top end. On a large workstation a plain `make` will reach for most of the cores, which on a laptop that also runs your editor and your test suite is a decision the Makefile made for you.
The escape hatch exists, since exporting `CMAKE_BUILD_PARALLEL_LEVEL` yourself bypasses the calculation, but the README does not mention it. A developer whose build behaves differently from CI, or whose build is memory-bound rather than CPU-bound, has to find that variable in the Makefile rather than in the documentation.
Three test binaries, three output directories, and two documented commands
The README tells you to run `make unit` and `make allunit` to verify your version works after making changes, and to run `make` in the root directory to compile the sources, with `make debug` for a non-optimized build. The Makefile behind those targets is more layered than that.
`UNITTEST_BINARY` defaults to `test/unittest`, with `.exe` appended when `$(OS)` is `Windows_NT`. A separate variable, `SMOKE_UNITTEST`, points at the same binary but under `build/relassert/`, and `SMOKE_RUNNER` points at `build/relassert/test/run`. Add to that `UNITTEST_SLOW_FLAGS` defaulting to `--track-runtime=100` and `UNITTEST_HUGE_FLAGS` defaulting to `--workers=50%` plus the slow flags.
There is also a passthrough for extra parameters, a `T` variable documented in a Makefile comment as allowing `make smoke T=...`, so you can append flags to a specific run without editing anything.
The performance path is separate, gated behind two environment variables, and it ends in a binary you invoke by path rather than a make target:
BUILD_BENCHMARK=1 BUILD_TPCH=1 make
./build/release/benchmark/benchmark_runnerThe consequence is that at least three entry points exist and the file names two, the difference between `unit` and `allunit` is not defined anywhere a reader would look, and the two spellings of the unittest binary mean a test run from the source tree and a smoke run from the build tree are not reading the same artifact.
The Makefile builds its own Python virtualenvs for format and codegen
The development section lists three requirements: CMake, Python 3 and a C++17 compliant compiler. The Makefile treats Python as more than that. It sets `PYTHON ?= python3` and then defines two separate environments under `.cache/`, one called `format-venv` and one called `capigen-venv`, each with its own interpreter path and its own setup dependency target.
The first is formatting, with `FORMAT_PYTHON` pointing into the format environment and a `format` target among the .PHONY list. The second is API generation, with `CAPIGEN_PYTHON` pointing into the capigen environment. The repository root backs this up with `api_spec/`, a Doxyfile for documentation, and a `.clang-format` for the C++ side.
The consequence is that a build from source will create directories and install packages under `.cache/` that the stated requirements never mention. If your environment restricts writes to the checkout, or if you assumed Python was needed only to run a test, you find out from a failed setup step rather than from the documentation. Two Python environments for two maintenance chores is also the sort of thing that quietly needs Python at a version your package manager did not choose.
Windows is handled as a file suffix, and falls back to a single build job
The Makefile branches on `$(OS)`. When it equals `Windows_NT`, an executable suffix variable is set to `.exe`, and that suffix is appended to the unittest binary path. That is the extent of the Windows accommodation in this file.
Now put that next to the CPU detection. The chain tries `nproc`, then `sysctl -n hw.ncpu`, then the `NUMBER_OF_PROCESSORS` environment variable, and otherwise prints 1. Those are Unix tools. On a Windows environment where none of them resolves, the detected count is 1, the 80 percent calculation clamps to a single job, and the exported `CMAKE_BUILD_PARALLEL_LEVEL` is 1.
So a Windows build driven through this Makefile runs serially by default, and the file that tells you how to build says nothing about it. There is a Windows build path, in other words, and it is the slow one, and the reason lives in a shell conditional in a Makefile.
The `.exe` suffix is the part that does work, which is a reasonable trade. The gap is that the parallelism fallback and the suffix handling were written for different platforms and only one of them noticed.
Three recent releases are all titled Bugfix Release, on a 1.5 line
The three most recent tags are v1.5.4 dated 2026-06-17, v1.5.5 dated 2026-07-22, and v1.5.6 dated 2026-09-28. Every one of them carries the title Bugfix Release. The line is 1.5 throughout, with no minor bump among the three, and the last push to the repository is 2026-09-29, a day after the v1.5.6 tag.
Read as a release cadence, that is a maintenance line rather than a feature line. If you are waiting for something new to land, the 1.5 series is not where it is arriving, and the file gives you no signal about which line is. The support section links to an `endoflife.date` page for the project, which is where the lifecycle of each line is actually tracked.
Now the second thing in that same top-level listing. Alongside AGENTS.md and CLAUDE.md there is a file called AI_POLICY.md, and none of the three is mentioned in the README.
That matters more than it sounds. A policy file at the root of a project with a CONTRIBUTING.md and a CODE_OF_CONDUCT.md governs the terms on which code gets in, and for a project of this size a contributor who never opens it may find out the terms after writing the work rather than before. The `AGENTS.md` and `CLAUDE.md` files point the same way, toward machine instructions for automated tooling. The README's Contributing line sends you to the contributing guideline, and stops there.
Editorial conclusion
Reach for DuckDB when your workload is analytical, when the data is sitting in CSV or Parquet files, and when you want a SQL dialect with nested correlated subqueries, window functions, collations and array, struct and map types without standing up a server. Skip it if you need the file to tell you how to install it, because the installation section is a link, and if you need a like-for-like speed comparison against PostgreSQL, ClickHouse or Polars, because the file makes no comparison and the only benchmark route is a guide you have to build for yourself. Before adopting, check the release line, since v1.5.4, v1.5.5 and v1.5.6 are all titled Bugfix Release, and read AI_POLICY.md and AGENTS.md at the repository root, which govern contributions and are not mentioned in the README.
Frequently asked questions
What is DuckDB used for?
It is an in-process analytical SQL database management system, and the file calls it a high-performance analytical database system designed to be fast, reliable, portable and easy to use. The dialect covers arbitrary and nested correlated subqueries, window functions, collations, and complex types including arrays, structs and maps, and CSV or Parquet files are read by referencing them in the FROM clause.
Is DuckDB completely free?
The repository is MIT licensed and ships a LICENSE file. The README describes no commercial or enterprise edition and no paid tier, and it points at an endoflife.date page and a support options page under ducklabs.com for lifecycle and support questions.
how to install duckdb
The Installation section is a single sentence pointing at https://duckdb.org/docs/installation/. No command, package name or platform list appears in the file, and every command it does give is a contributor command such as `make`, `make debug`, `make unit` or `make allunit`.
how to use duckdb cli
A standalone CLI application is one of the available clients, linked at https://duckdb.org/docs/current/clients/cli/overview. The README gives no CLI invocation, no flags and no dot-commands, and its only runnable SQL is a file read such as `SELECT * FROM 'myfile.csv';`.
Is DuckDB faster than PostgreSQL?
The README makes no comparison with PostgreSQL or any other system, and reports no benchmark numbers. It describes DuckDB as fast, reliable, portable and easy to use, and points performance testing at `BUILD_BENCHMARK=1 BUILD_TPCH=1 make` followed by `./build/release/benchmark/benchmark_runner`, with details in the Benchmark Guide.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/duckdb-duckdb)