The data we touch in an ordinary workday mostly lives in files. CSVs from the finance team, Parquet partitions from a pipeline, JSON dumps from an API. When you actually want to ask questions of that data, the classic move is to load it into a database first: stand up a server, design a schema, wait out an import. DuckDB inverts the arrangement. The database comes to the files.
What it is
DuckDB is an in-process, columnar analytical database, written in C++ and open source under the MIT license. Mark Raasveldt and Hannes Mühleisen started it in 2018 while working as database researchers at Centrum Wiskunde & Informatica (CWI) in Amsterdam, and announced version 0.1 at SIGMOD in 2019. DuckDB Labs, the company that funds its full-time developers, spun out of CWI in July 2021. The project hit 1.0.0 on June 3, 2024, with a guarantee of backward compatibility for its storage format; the current stable line is 1.5, released in March 2026, and the team previewed 2.0 in August. None of this is niche enthusiasm: the GitHub repository passed 40,000 stars in August 2026, and the team reports over 50 million monthly downloads of the Python package alone.
The server is optional
Compared with Postgres or MySQL, the first thing to unlearn is the server. There isn't one. DuckDB runs inside your process — the CLI is a single binary with no configuration file, no port, no credentials — and it opens whichever file you point it at. pip install duckdb gets you the same engine in Python.
Ask your CSV a question
Say the finance team drops sales_2026.csv in your directory. Open the CLI and ask:
SELECT *
FROM 'sales_2026.csv';
Nothing was loaded, configured, or imported. DuckDB sniffs the file, infers the types, and treats it like a table, so everything else works the way SQL taught you:
SELECT region, SUM(amount) AS revenue
FROM 'sales_2026.csv'
GROUP BY region
ORDER BY revenue DESC;
Joins cross files too — orders.csv against customers.csv — as if both were tables in the same schema, because to DuckDB they are.
Parquet, globs, and object stores
Parquet files get the same treatment, plus the tricks that make file queries fast instead of merely convenient. DuckDB pushes filters down into the Parquet scan and reads only the columns a query touches. read_parquet('exports/*.parquet') fans out across a whole directory, and the source can be an https:// URL. When files aren't enough, the extension system widens the door: httpfs reads and writes over HTTP and S3, and the postgres and sqlite extensions query those databases directly from the same engine, no ETL in between.
Python without the pandas dance
Python is where it gets quietly life-changing. duckdb.sql("SELECT * FROM df") runs against your pandas DataFrame by name, without copying it out, and the same query syntax that works on files works on the DataFrame. A file-to-DataFrame-to-file loop that used to take fifteen lines of pandas takes one.
When to reach for it
Reach for DuckDB when the data is already in files and the question is analytical: poking at an export, sanity-checking a pipeline, munging data between formats, or powering analytics inside an application where installing a database server would be absurd. It is not a transactional database, and it doesn't pretend to be — Postgres stays for OLTP, DuckDB takes the analysis. That's the real point: you no longer have to move data somewhere before you can understand it. The query comes to the files, wherever they are.
Fair warning: once you've queried a CSV this way, every spreadsheet that lands in your inbox starts looking like a database.