Your universal data wrangling tool
Search Shortcut cmd \+ k | ctrl \+ k
Your universal
data wrangling toolDatabase anywhere
DuckDB is an analytical database system that you can deploy anywhere: from edge devices to servers with hundreds of cores.
Friendly SQL
DuckDB has a friendly and expressive PostgreSQL-inspired query language.
Extensible
Extensions can introduce functions and support for new formats.
Native clients
DuckDB offers idiomatic and performant APIs for all major programming languages.
Speaks your formats
Read and write popular formats such as CSV, JSON, Parquet, and Iceberg – locally or in object storage.
Free & open-source
DuckDB and related projects are MIT-licensed, governed by the independent DuckDB Foundation.
More than a query engine
The Duck Stack includes a database, a protocol, and offers first-class support for lakehouse formats.
- DuckDB
- Quack
- DuckLake
- Iceberg
- Command line
- Python
- Go
- Java
- Node.js
- ODBC
- Rust
DuckDB
An analytical SQL database that can run in-process. Simple, fast, and portable. It is the stack builds on.
Explore DuckDBCSV file App Parquet Database file
Quack
The client-server protocol for DuckDB. With Quack, both your client and the server are full-fledged DuckDB instances, so you can access a remote database but also run computations on the client side.
Explore QuackApp Notebook Server
DuckLake
DuckLake is a lakehouse format built on SQL. Save your data in object storage and use a SQL database as a catalog for scalability, simplicity, and speed.
Explore DuckLakeClient Client Catalog Storage
Iceberg
DuckDB has first-class Apache Iceberg support: you can read and write Iceberg tables directly from DuckDB with high performance.
Explore IcebergClient Client Catalog Storage
Protocols & storage
Cloudflare Amazon Web Services Microsoft Azure Google Cloud Hugging Face
Databases
SQLite MySQL PostgreSQL ODBC MotherDuck
Clients
CLI Python Go Java Node.js C C++ R Rust ODBC
Formats
Parquet CSV JSON Vortex Lance Iceberg Delta Lake DuckLake DuckDB Geospatial Avro Excel Arrow
Install DuckDB
Start using DuckDB in your environment.
curl https://install.duckdb.org | bashSystem detected:
pip install duckdbnpm install @duckdb/node-apicurl https://install.duckdb.org | bashcurl https://install.duckdb.org | bashduckdb\_odbc-osx-universal.zip
duckdb\_odbc-windows-amd64.zip
cargo add duckdb --features bundledgo get github.com/duckdb/duckdb-go/v2[](https://duckdb.org/2026/10/02/dimension-tables.html "Faster String Aggregations with Dimension Tables")
Faster String Aggregations with Dimension Tables
2026-10-02
16 min
DuckDB Team
[](https://duckdb.org/2026/09/29/jev.html "Jev and DuckDB: Plain-English Conditions in SQL")
Jev and DuckDB: Plain-English Conditions in SQL
2026-09-29
8 min
Geertjan Wielenga, Gábor Szárnyas
[](https://duckdb.org/2026/09/28/announcing-duckdb-156.html "Announcing DuckDB 1.5.6")
Announcing DuckDB 1.5.6
2026-09-28
3 min
The DuckDB team
-- Get the top-3 busiest train stations
SELECT
station_name,
count(*) AS num_services
FROM train_services
GROUP BY ALL
ORDER BY num_services DESC
LIMIT 3;-- Load CSV file to a table. DuckDB auto-detects
-- the CSV's format, column name and types
CREATE TABLE stations AS
FROM 'https://blobs.duckdb.org/stations.csv';-- Directly query Parquet file over HTTPS
SELECT
station_name,
count(*) AS num_services
FROM 'https://blobs.duckdb.org/train_services.parquet'
GROUP BY ALL
ORDER BY num_services DESC
LIMIT 10;-- Find the top-3 longest domestic train routes
SELECT s1.name_short, s2.name_short, d.distance
FROM distances d
JOIN stations s1 ON d.station1 = s1.code
JOIN stations s2 ON d.station2 = s2.code
WHERE s1.country = s2.country
AND s1.code < s2.code
ORDER BY distance DESC
LIMIT 3;-- List the closest IC stations (as the crow flies)
SELECT
s1.name_long AS station1,
s2.name_long AS station2,
ST_Distance(
ST_Point(s1.geo_lng, s1.geo_lat),
ST_Point(s2.geo_lng, s2.geo_lat)
) * 111_139 AS distance
FROM stations s1, stations s2
WHERE s1.type LIKE '%Intercity%'
AND s2.type LIKE '%Intercity%'
AND s1.id < s2.id
ORDER BY distance ASC
LIMIT 3;# Get the top-3 busiest train stations
import duckdb
duckdb.sql("""
SELECT station, count(*) AS num_services
FROM train_services
GROUP BY ALL
ORDER BY num_services DESC
LIMIT 3;
""")# Reading and writing Pandas dataframes
import pandas as pd
import duckdbdf_in = pd.DataFrame({
'station': ['Delft', 'Delft', 'Gouda', 'Gouda'],
'day': ['Mon', 'Tue', 'Mon', 'Tue'],
'num_services' : [22, 20, 27, 25]})
Run query on a dataframe and return a dataframe
df_out = duckdb.sql("""
SELECT station, sum(num_services)
FROM df_in
GROUP BY station
""").to_df()# Create custom user-defined function
import duckdbdef plus_one(x):
return x + 1
con = duckdb.connect()
con.create_function('plus_one', plus_one,
['BIGINT'], 'BIGINT', type='native')
con.sql("""
SELECT sum(plus_one(i)) FROM range(10) tbl(i);
""")
# Find the largest sepals/petals in the Iris data set
library(duckdb)con <- dbConnect(duckdb())
duckdb_register(con, "iris", iris)
query <- r'(
SELECT count(*) AS num_observations,
max("Sepal.Width") AS max_width,
max("Petal.Length") AS max_petal_length
FROM iris
WHERE "Sepal.Length" > 5
GROUP BY ALL
)'
dbGetQuery(con, query)
# Find the largest sepals/petals in the Iris data set
using duckplyr
library("duckplyr")iris |>
filter(Sepal.Length > 5) |>
group_by(Species) |>
summarize(
num_observations = n(),
max_width = max(Sepal.Width),
max_petal_length = max(Petal.Length),
na.rm = TRUE) |>
collect()
# Find the largest sepals/petals in the Iris data set
using dplyr
library("duckdb")
library("dplyr")con <- dbConnect(duckdb())
duckdb_register(con, "iris", iris)
tbl(con, "iris") |>
filter(Sepal.Length > 5) |>
group_by(Species) |>
summarize(
num_observations = count(),
max_width = max(Sepal.Width),
max_petal_length = max(Petal.Length),
na.rm = TRUE) |>
collect()
// Get a list of train stations by traffic
Connection conn =
DriverManager.getConnection("jdbc:duckdb:");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(
"""
SELECT station_name,
count(*) AS num_services
FROM train_services
GROUP BY ALL
ORDER BY num_services DESC;
""");System.out.println(rs.next());
// Perform bulk inserts using the Appender API
DuckDBConnection conn = (DuckDBConnection)
DriverManager.getConnection("jdbc:duckdb:");
Statement st = conn.createStatement();
st.execute(
"CREATE TABLE person (name VARCHAR, age INT)");var appender = conn.createAppender(
DuckDBConnection.DEFAULT_SCHEMA, "person");
appender.beginRow();
appender.append("MC Ducky");
appender.append(49);
appender.endRow();
appender.close();
// Get the top-3 busiest train stations in May
import { DuckDBInstance } from '@duckdb/node-api';
const instance = await DuckDBInstance.create();
const connection = await instance.connect();
const reader = await connection.runAndReadAll(
`SELECT station_name, count(*) AS num_services
FROM
'https://blobs.duckdb.org/train_services.parquet'
WHERE monthname(date) = 'May'
GROUP BY ALL
ORDER BY num_services DESC
LIMIT 3;`
);
console.table(reader.getRows());// Web Service Integration:
// Create endpoint to generate numbers
import express from "express";
import { DuckDBInstance } from '@duckdb/node-api';
const app = express();
const instance = await DuckDBInstance.create();
const connection = await instance.connect();
app.get("/getnumbers", async (req, res) => {
const reader = await connection.runAndReadAll(
"SELECT random() AS num FROM range(10)");
res.end(JSON.stringify(reader.getRows()));
});app.listen(8082, () => console.log(
"Go to: http://localhost:8082/getnumbers"));
