Announcing DuckDB 2.0.0 LTS “Cinnamon Teal”
DuckDB 2.0 LTS adds a client-server protocol, asynchronous I/O for faster storage access, and a powerful VARIANT type for semi-structured data.
Deep dive
- Requires C++17 compiler for builds.
- Asynchronous I/O improves throughput on object storage like S3.
- VARIANT type stores schema-less data with columnar performance through data shredding.
- Trigger support allows for incremental maintenance of materialized views.
- CLI now includes an 'agent mode' for LLM-based tools to optimize output.
- New PEG-based parser replaces the YACC/Bison implementation.
- Experimental extension repositories allow organizations to host and sign custom extensions.
Decoder
- Quack Protocol: DuckDB's native client-server protocol that enables remote database access.
- VARIANT Type: A storage format that maintains columnar performance while supporting semi-structured, schema-less data like JSON.
- PEG (Parsing Expression Grammar): A formal language for describing syntax that avoids the conflicts inherent in YACC/Bison parsers.
- Shredding: The process of decomposing nested/semi-structured data into individual typed columns for efficient storage and query execution.
Original article
Announcing DuckDB 2.0.0 LTS “Cinnamon Teal”
TL;DR: The DuckDB team is happy to announce that today we're releasing DuckDB version 2.0.0 LTS, codenamed “Cinnamon Teal” (Spatula cyanoptera). This is our biggest feature release so far, and it ships a polished version of the Quack protocol, asynchronous I/O, a first-class VARIANT type, agent mode, triggers, an extensible SQL parser and much more, built from close to 20,000 commits since DuckDB 1.5.
We are proud to release DuckDB 2.0.0, codenamed “Cinnamon Teal” after the Spatula cyanoptera, a strikingly reddish-brown duck found in the western Americas.
While DuckDB 1.0 was all about stability and backward compatibility, DuckDB 2.0 is above all a feature release. In this blog post, we summarize the highlights and then walk through the breaking changes and how to migrate. We showcased many of the new features in “A Preview of DuckDB v2.0”, which covers each one in more depth. For the complete release notes, see the release page on GitHub.
Tip: To install the new version, please visit the installation page. Some clients, such as the CLI and Python, are already available. Other client libraries (e.g., R and Rust) and some extensions can take a few days to release due to the extra changes and review rounds required.
With this release, there are currently three DuckDB lines available. DuckDB 2.0 is a long-term support (LTS) release with support until at least October 2027. The previous LTS release, version 1.4, is still supported until November 17, 2026. To ensure a smooth transition and allow sufficient time for testing, we extended the support period of DuckDB 1.5 until March 2027, effectively also turning it into an LTS release.
DuckDB as a Server
DuckDB has been an in-process database since day one. In DuckDB 1.5.3, released in May, we introduced the Quack protocol that lets you run DuckDB in a traditional client-server setup, along with the quack extension, which implements DuckDB's native protocol, so any DuckDB process can serve its databases.
Quack and CONNECT
DuckDB 2.0.0 ships a polished version of the Quack protocol with substantial performance and stability improvements. It also introduces the new CONNECT statement that allows attaching and switching to a remote database in a single command for better ergonomics:
DuckDB server
CALL quack_serve(
token = 'my_token'
);
CREATE TABLE events
(date DATE, name VARCHAR);
INSERT INTO events VALUES
('2027-04-07',
'DuckCon #8');
DuckDB client
ATTACH 'quack:localhost'
AS qk (TOKEN 'my_token');
CONNECT qk;
SELECT * FROM events;
┌────────────┬────────────┐
│ date │ name │
│ date │ varchar │
├────────────┼────────────┤
│ 2027-04-07 │ DuckCon #8 │
└────────────┴────────────┘
For simplicity, this example runs the server and the client on the same machine. By default, the server only listens on localhost. To accept connections from other machines, keep the server on localhost and put it behind a TLS-terminating reverse proxy. The allow_other_hostname option, which exposes the server directly, is only meant for testing.
The CONNECT statement is not limited to Quack: it points your session at any remote database that supports it, including PostgreSQL and MySQL. For these, the new remote pushdown optimizer ships queries directly to the remote server instead of pulling tables over the wire.
Quack in the CLI
The CLI also has shortcuts for setting up a Quack client-server pair: the new -serve and -connect arguments start a Quack server or connect to one directly from the command line:
CLI server
duckdb -serve
CLI client
duckdb -connect
Performance
Asynchronous I/O
DuckDB 2.0 introduces asynchronous I/O for reading Parquet and CSV files, as well as DuckDB's native storage format. The I/O layer now scales independently from the query processing layer, issuing reads in the background and keeping multiple requests in flight. This means far more parallelism for remote reads and dramatically faster queries on object storage such as s3://.
The VARIANT Type Becomes a First-Class Citizen
The VARIANT type stores semi-structured, schema-less data such as JSON while keeping the performance of columnar execution. So you can think of it as JSON on steroids: a VARIANT column can store differently shaped data in every row, but unlike JSON it is not a text format.
DuckDB 2.0 detects the common structure in your data and “shreds” it, so it compresses well and executes fast. The pipeline works end to end, from shredded execution straight out of storage to shredded VARIANT reading and writing for Parquet, backed by a family of variant_* functions.
Agent Mode in the CLI
Coding agents such as Claude Code, Codex and Cursor increasingly drive the DuckDB CLI on their users' behalf. The 2.0 CLI detects when it is being run by an agent and switches to agent mode: it prints compact Markdown tables instead of padded boxes, says clearly when a result was truncated, stops runaway queries early and reports errors as JSON.
Extensibility
A Brand New SQL Parser
DuckDB has always used a parser derived from PostgreSQL's. In 2.0, our own modern, extensible PEG-based parser, which debuted as an opt-in feature in DuckDB 1.5, becomes the default. Extensions can now hook into the grammar itself, so expect extensions that expose entirely new SQL syntax. Error messages now come with precise source locations. The new parser is designed to be compatible with the old one, apart from a few deliberate changes listed in the migration guide.
Write Extensions Once and Host Them Yourself
DuckDB 2.0 ships a revamped C API v2, which is considerably more powerful than its predecessor and exposes components such as file systems and table functions to extensions.
You can also register and host your own trusted extension repositories, so an organization can host and sign its own extensions and have them install and load just like the built-in ones:
SET allow_extension_repositories = 'allowed';
CREATE EXTENSION REPOSITORY my_repo
WITH PREFIX 'https://extensions.example.org';
INSTALL AND LOAD my_ext FROM my_repo;
Core Extension Updates
- We released DuckLake 1.1, including a new specification and reference implementation.
- The Iceberg extension strives to become a feature-complete implementation.
- The Delta extension can create Delta tables with
CREATE TABLE(including partitioning and Delta table properties), supports time travel and improvesVARIANTsupport.
SQL Features
Triggers
DuckDB 2.0 delivers triggers: the CREATE TRIGGER statement with BEFORE and AFTER triggers, FOR EACH ROW and FOR EACH STATEMENT, transition tables via REFERENCING OLD/NEW TABLE, multiple triggers per event, RETURNING on triggered tables and DROP TRIGGER.
SQL Dialect Additions
- The
$variableshorthand lets you write$xin most places where an expression is allowed, instead ofgetvariable('x'). - Data-modifying CTEs let you use
INSERT,UPDATE,DELETEandCOPYas pipeline steps. NEARESTjoins turn top-k similarity search into a join clause.- Nested schemas allow schemas within schemas, e.g.,
CREATE SCHEMA finance.reports. - JSON mutation functions
json_set,json_insert,json_replaceandjson_removereturn modified copies of JSON documents.
Migrating to 2.0
DuckDB 2.0 comes with a small set of breaking changes. For most users, upgrading is straightforward, but complex deployments running many DuckDB processes need more care. The storage format is the most likely source of problems: DuckDB versions before 2.0 cannot read database files created by DuckDB 2.0.
Internals and Deprecations
Compiler Requirements
Following DuckDB's long stint on C++11, DuckDB 2.0 now requires a C++17 compiler.
Timezones, Calendars and Collations Without ICU
Timezone-aware timestamps, calendars and collations have always been powered by the ICU library. In 2.0, the ICU library is gone entirely: the icu extension now implements timezones, calendars and collations itself, with the timezone data built directly from the IANA database.
Deprecations
Lambda Syntax
The old single-arrow lambda syntax (x -> x + 1) is now disabled by default. Use the Python-style syntax instead.
Amalgamation Builds
The amalgamation build, which bundles DuckDB's entire source code into a single header and a single source file, is now deprecated.
Gradual Phase-Out of macOS x86_64
We are gradually phasing out osx_amd64 from the list of fully supported platforms. DuckDB 2.1 will stop supporting osx_amd64.
Summary
These were a few highlights, but there are many more features and improvements in this release. There have been almost 20,000 commits by many contributors since DuckDB 1.5, shipping smaller features as well as performance and usability improvements.
Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi