DuckDB 2.0 is turning a database embedded in one application into a database that other processes can query. Its Quack protocol lets a DuckDB process serve its catalog over HTTP, while the new CONNECT statement routes SQL to that process. The useful question is where execution happens and what data must cross the wire.
The 2.0 preview puts server mode beside asynchronous I/O, a new storage format, a new parser, and an expanded C API. As of 25 September 2026, Quack is available as a beta extension and 2.0 remains a preview. DuckDB’s release calendar currently targets 21 October for 2.0.0; that date is tentative.
The file lock becomes a service boundary
In its usual embedded mode, DuckDB runs inside the application that calls it. The application and database share a process and can avoid a network hop. This arrangement suits notebooks, command-line analysis, local pipelines, and services whose data access can be coordinated inside one process.
That embedded paradigm is central to DuckDB’s ecosystem adoption. In September 2026, dbt announced that dbt v2 now ships with a native DuckDB adapter built directly into its Rust-based Fusion engine, letting data teams execute local transformation models and CI checks straight off Parquet files without spinning up cloud data warehouses:
That process boundary has a practical consequence. For a native DuckDB database file, DuckDB permits one read-write process, or multiple read-only processes with no writer. Within the writer process, multiple threads can write concurrently under MVCC and optimistic concurrency control. Appends do not conflict; competing updates to the same row can. Putting the file on a shared volume does not turn it into a conventional multi-process database.
Quack gives the writer process a network interface. Clients connect to that process instead of opening the same writable file independently. This is the important architectural shift: the storage engine still has a serving process, but other processes can issue queries and receive results. DuckDB’s Quack documentation says the server exposes the databases and schemas visible to the session that starts it.
CONNECT decides where SQL executes
There are two useful ways to think about a remote DuckDB. An attached remote catalog lets a client refer to remote tables. A CONNECT block points the client’s session at a remote engine, so the SQL inside that block executes there and results return to the client. The 2.0 preview illustrates the latter pattern:
The count(*) result is small even if events is large. Executing that aggregation where the data lives can keep millions of input rows off the client connection. If the client instead requests millions of rows, the network and result decoding become part of the query’s cost. This is an engineering inference from the placement of execution and result transfer, not a benchmark claim.
CONNECT also targets PostgreSQL and MySQL in the 2.0 preview. DuckDB says its new remote pushdown optimizer sends SQL to those servers rather than first pulling whole tables into the local process. That is a useful distinction: a remote catalog name alone does not tell you where filters, joins, and aggregation run. Inspect the plan and measure bytes moved before treating a cross-database query as cheap.
One query takes one protocol round trip
Quack uses HTTP for its transport and DuckDB’s own application/duckdb serialization for requests and results. After the connection handshake, a small query can complete in one request-response pair. Larger results stream in chunks through follow-up FETCH requests, which can run in parallel. The protocol preserves DuckDB types such as nested values and decimals without converting the entire result into JSON or text.
That design addresses a real mismatch between an analytical engine and a row-oriented client protocol. DuckDB processes data in vectors; its documented standard vector size is 2,048 tuples. A protocol that repeatedly converts columnar work into individual text rows can spend time on formatting and transfer that the query engine did not need. Quack’s internal serialization reduces that conversion cost, although its proprietary wire format also means generic database clients need a Quack implementation.
DuckDB’s own Quack launch benchmark moved 60 million TPC-H lineitem rows in 4.94 seconds, compared with 17.40 seconds through Arrow Flight SQL and 158.37 seconds through a PostgreSQL client path. These are vendor-run measurements on two same-zone AWS Arm instances, not a universal ranking of database protocols. The compared clients also differ in whether they parallelize reads. For a production decision, repeat the measurement with your row width, network, client, and query shape.
Server mode changes the operating costs
An embedded query can run without opening a socket or authenticating a remote caller. A Quack deployment adds a process that must stay alive, an HTTP path, credentials, and observable resource limits. DuckDB notes that each Quack request opens a fresh TCP connection by default; enabling httpfs_connection_caching reuses connections and can reduce repeated handshake cost. Network latency still matters for short queries, while wide results consume bandwidth and client memory.
The larger cost is control. Quack’s default token authenticates a client but its default authorization hook permits every query. The server can expose the full SQL surface, including writes to objects visible to its session. It binds to localhost by default and does not terminate TLS itself. DuckDB recommends a TLS-terminating reverse proxy for connections beyond the local machine. Anyone deploying it for multiple users needs a deliberate authorization model, secret handling, and resource isolation; possession of the shared token is not a read-only role.
Concurrency also remains a workload question. Quack allows multiple processes to reach the one serving database process. It does not make contended updates disappear: DuckDB’s optimistic concurrency model can still reject transactions that modify the same rows. A queue of short analytical reads and append-heavy jobs is a different demand from thousands of tiny conflicting updates. The latter deserves a workload benchmark before migration.
Remote storage gets a separate engine change
The network story in 2.0 extends beyond Quack. DuckDB is adding asynchronous I/O to let scan tasks keep remote reads in flight while worker threads do other work. Its engineering write-up explains the read-ahead queue and memory governor: fetching more Parquet row groups improves network utilization, but prefetched pages occupy memory. As memory pressure rises, the queue contracts.
In one published S3 benchmark, TPC-H Query 6 over a roughly 22 GB Parquet file took 8.230 seconds on DuckDB 1.5.5 and 2.844 seconds on a 2.0 development build. The test used an EC2 instance with 64 vCPUs in the same region as the bucket, cold reads, and five-run means. It shows what asynchronous I/O can do when request latency prevents the old scan from filling available network bandwidth. It does not imply that every local query becomes three times faster; DuckDB reports a much smaller gain on cold local SSD reads and negligible gain on cached reads.
Read-ahead also depends on data layout. In DuckDB’s experiment, a Parquet file with very few large row groups exposed too little parallelism to saturate the link. The fastest tested layout used 306 row groups; a single enormous row group took much longer. The practical point is that a faster storage scheduler cannot manufacture parallel scan units that the file does not contain.
A deployment decision follows the data path
| Workload | Likely starting point | Measure first |
|---|---|---|
| One app reads local files | Embedded DuckDB | Scan time and peak memory |
| Several apps query one writable DuckDB file | Quack serving process | Query latency, result bytes, write conflicts |
| Cold analytics over Parquet on object storage | 2.0 asynchronous scan preview | Row groups, request count, memory, bandwidth |
The test for Quack is therefore specific. Start with the same query in embedded mode and through the serving process. Compare server CPU time, end-to-end latency, bytes returned, memory, and concurrent write failures. Run a second case with the largest result your client actually consumes. If the client only needs an aggregate, keep that aggregation on the server. If it needs a full export, budget for the transfer.
DuckDB 2.0 broadens where its engine can be used, but its strongest case is still tied to query placement and efficient scans. Quack makes one process reachable; asynchronous I/O makes remote storage less likely to idle the compute engine. The useful architecture is the one that minimizes unnecessary movement of input rows and results while meeting the application’s concurrency and access requirements.
Frequently asked questions
Is Quack new in DuckDB 2.0?
No. DuckDB released Quack as a beta extension before 2.0. The team says it plans to graduate the feature to stable in 2.0; details can still change before the release.
Can several processes write the same DuckDB database?
They can send writes through a Quack serving process. They should not independently open the same native file for read-write access. Concurrent updates that touch the same rows can still produce transaction conflicts.
Does Quack make DuckDB a distributed database?
Quack gives a DuckDB process a network protocol and allows clients to run remote queries. That is a client-server deployment. The documented feature does not, by itself, establish automatic replication or distributed execution across a cluster.
