DuckDB 2.0.0 LTS adds Quack server protocol, async I/O and triggers

DuckDB 2.0.0 LTS adds Quack server protocol, async I/O and triggers

The DuckDB team has released DuckDB 2.0.0 LTS, codenamed "Cinnamon Teal" after Spatula cyanoptera, a reddish-brown duck from the western Americas. The team calls it its biggest feature release so far, built from close to 20,000 commits since DuckDB 1.5. Where DuckDB 1.0 was about stability and backward compatibility, 2.0 is, in the team's words, above all a feature release.

Support and availability: DuckDB 2.0 is a long-term support release with support until at least October 2027. The previous LTS line, 1.4, stays supported until late November 2026. To give users time to test the move, the team extended support for DuckDB 1.5 until March 2027, which effectively makes it an LTS release too. That leaves three DuckDB lines available. The CLI and Python client are available now; other clients (Go, R, Java) and some extensions can take a few days because of extra changes and review rounds.

DuckDB as a server. DuckDB has always been an in-process database. The Quack protocol, introduced in DuckDB 1.5.3 in May, lets it run in a client-server setup, and the quack extension means any DuckDB process can serve its databases. Version 2.0.0 ships a polished Quack with substantial performance and stability improvements, plus a new CONNECT statement that attaches and switches to a remote database in one command. In the example, the server calls quack_serve with a token, and the client runs ATTACH 'quack:localhost' with that token and then CONNECT. By default the server listens only on localhost. To accept connections from other machines, it should stay on localhost behind a TLS-terminating reverse proxy; the allow_other_hostname option, which exposes the server directly, is only meant for testing. CONNECT also works with other remote databases that support it, including PostgreSQL and MySQL, and a new remote pushdown optimizer ships queries to the remote server instead of pulling tables over the wire. The CLI gets -serve and -connect arguments as shortcuts.

Performance. DuckDB 2.0 adds asynchronous I/O for reading Parquet, CSV and DuckDB's native storage format. The I/O layer now scales independently from query processing, issuing reads in the background with multiple requests in flight. The team says this means far more parallelism for remote reads and dramatically faster queries on object storage such as s3://. A separate blog post covers the design and shows network throughput with and without async I/O.

VARIANT. The type stores semi-structured, schema-less data such as JSON while keeping columnar performance; the team describes it as JSON on steroids, since each row can have a different shape but it is not a text format. VARIANT first appeared in 1.5; 2.0 fully integrates it. DuckDB detects the common structure in the data and shreds it so it compresses well and runs fast, end to end: shredded execution straight from storage, shredded VARIANT reading and writing for Parquet, and a family of variant_* functions such as variant_type and variant_keys.

Agent mode. Coding agents such as Claude Code, Codex and Cursor increasingly drive the DuckDB CLI for their users. The 2.0 CLI detects when an agent is running it and switches to agent mode: compact Markdown tables instead of padded boxes, clear notice when a result is truncated, early stopping of runaway queries, and errors reported as JSON. Long-running queries report their expected cost before running so the agent can decide whether to wait. In the team's TPC-H experiments, agent mode cut the amount of DuckDB output the model had to read by 59%. The -agent flag turns it on for manual testing, and -no-agent turns it off.

Extensibility. DuckDB used a parser derived from PostgreSQL's since its first commit in 2018, generated with YACC/Bison as an LALR(1) parser, where growing the grammar risked shift/reduce and reduce/reduce conflicts. In 2.0 the team's own PEG-based parser, opt-in since 1.5, becomes the default. A PEG grammar tries alternatives in the order written, so adding syntax no longer risks breaking unrelated rules. Extensions can now hook into the grammar itself, so the team expects extensions that add new SQL syntax, and error messages carry precise source locations. The new parser is designed to be compatible with the old one; anyone who notices a difference is asked to file an issue, and SET enable_legacy_parser = true with the legacy_parser extension restores the old one.

DuckDB 2.0 also 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. It is not yet marked stable; the team wants field testing first. Organizations can also register and host their own trusted extension repositories: a repository is a name, a URL prefix and one or more RSA public keys trusted to sign its extensions, and the prefix can point at a local path, https, s3 and more. At CREATE time DuckDB fetches the public keys, pins them, and prints each key's SHA-256 fingerprint for comparison with one published out of band. The team says this feature is still a work in progress and its syntax may change.

Core extensions. DuckLake 1.1 is released with a new specification and reference implementation. The Iceberg extension adds REST catalog ATTACH options that derive a table's location from its namespace or load table metadata from the metadata-location file the catalog returns, plus options for the URL prefix and namespace separator. The Delta extension can create Delta tables with CREATE TABLE (including partitioning and table properties), supports time travel and improves VARIANT support. Dedicated posts are promised in the coming weeks.

Triggers. DuckDB 2.0 delivers CREATE TRIGGER 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. The classic use is audit tables that record what changed. Some combinations, such as BEFORE ... FOR EACH ROW and UPDATE ... FOR EACH ROW triggers, are not yet supported. Triggers can also maintain materialized views incrementally: the post's example keeps average age per nationality in an age_statistics table using one trigger for inserts and another for deletes, storing the sum and count next to the average, with a MERGE on insertion.

Key facts

  • DuckDB 2.0.0 LTS "Cinnamon Teal" is called the team's biggest feature release so far, built from close to 20,000 commits since DuckDB 1.5.
  • The Quack client-server protocol, first introduced in 1.5.3 in May, is polished in 2.0, and a new CONNECT statement attaches and switches to a remote database, including PostgreSQL and MySQL, in one command.
  • Asynchronous I/O for Parquet, CSV and native storage is said to make queries on object storage such as s3:// dramatically faster; the CLI gains an agent mode that cut output read by the model by 59% in the team's TPC-H experiments.
  • The PEG-based SQL parser becomes the default (the old one is restorable via the legacy_parser extension), VARIANT is fully integrated, and triggers arrive, with some combinations not yet supported.
  • DuckDB 2.0 has support until at least October 2027; DuckDB 1.4 is supported until late November 2026, and 1.5 is extended until March 2027.

Why it matters

DuckDB began as an in-process database, and 2.0 pushes well beyond that. The Quack protocol and CONNECT statement make client-server use a built-in option, and the new parser lets extensions add SQL syntax. Asynchronous I/O targets remote data, with the team promising dramatically faster queries on object storage. Triggers, including incremental maintenance of materialized views, add a feature set that DuckDB lacked before. The team contrasts the release with 1.0, which focused on stability and backward compatibility. It is also marked LTS, so users who want a stable base now have a long-supported line.

Who it affects

Anyone running DuckDB: analysts using the CLI or Python, teams reading Parquet or CSV from object storage such as s3://, and users of Go, R and Java clients, who may wait a few days for their libraries. Users of the 1.4 LTS line have until late November 2026, and the 1.5 line is supported until March 2027. Developers of extensions get the C API v2 and the ability to host their own signed extension repositories. People who use coding agents like Claude Code, Codex or Cursor to drive the DuckDB CLI get the new agent mode automatically.

How to use it

Install from the DuckDB installation page; the CLI and Python are available now. To try Quack, run CALL quack_serve with a token on the server, then ATTACH 'quack:localhost' with the token and CONNECT on the client, or use the CLI's -serve and -connect arguments. Keep the server on localhost and put it behind a TLS-terminating reverse proxy for other machines. Agent mode can be forced on with -agent for manual testing, or off with -no-agent. If the new parser causes trouble, run SET enable_legacy_parser = true with the legacy_parser extension and file an issue. A What's New in the Docs for 2.0 page links each feature to its documentation.

How solid is it

This is the DuckDB team's own announcement, so the claims are the vendor's. Performance statements are qualitative: the visible text gives no benchmark numbers for asynchronous I/O (only a reference to a throughput chart and a separate blog post), and none for VARIANT or the PEG parser. The 59% agent-mode figure comes from the team's TPC-H experiments, and the source does not name which model or agent was used. The part of the post covering breaking changes and migration guidance is not covered here, so check the original before upgrading.

Risks and caveats

Several pieces are explicitly unfinished. The C API v2 is not yet marked stable, custom extension repositories are a work in progress whose syntax may change, and some trigger combinations (BEFORE ... FOR EACH ROW and UPDATE ... FOR EACH ROW) are not yet supported. The new parser is meant to be compatible with the old one, but the team asks users to report differences. Exposing a Quack server directly via allow_other_hostname is only meant for testing. Other client libraries and some extensions may lag the release by a few days, and the source gives no date beyond that.

“While DuckDB 1.0 was all about stability and backward compatibility, DuckDB 2.0 is above all a feature release.”

— The DuckDB team, release announcement