DuckDB Quack Remote Protocol Guide: Client-Server for Embedded Analytics
DuckDB — the embedded analytics database that has been quietly winning hearts since 2019 — just made a move that changes the game. On May 12, 2026, the DuckDB team announced Quack, a native client-server remote protocol that lets DuckDB instances talk to each other over TCP and HTTP(S).
This is a big deal. DuckDB was always the "SQLite for analytics" — an embedded, in-process database that runs inside your application, not as a separate server. That simplicity is what made it beloved by data scientists, Python notebook users, and anyone who wants to run analytical queries without setting up a PostgreSQL cluster.
But the in-process architecture has a blind spot: you couldn't have multiple processes writing to the same database simultaneously. Want to insert telemetry data from 20 worker processes while a dashboard queries the same tables? You'd need workarounds — custom RPC layers, Arrow Flight SQL adapters, or the infamous "EleDucken" (DuckDB running inside PostgreSQL via extension).
Quack changes all of that. And it does it the DuckDB way: simple to set up, built on proven technologies like HTTP, and fast. On Hacker News, the announcement hit 190 points with passionate discussion.
What Is DuckDB Quack?
Quack is a remote query protocol that enables DuckDB to operate in a client-server architecture. The name is a playful reference to what two (or more) ducks do when they want to talk to each other. But the protocol itself is serious engineering:
- Transport: Protobuf-based serialization over HTTP(S) and native TCP
- Encryption: TLS for non-local connections, auto-generated auth tokens
- Authentication: Token-based default, fully customizable via callback functions
- Authorization: Per-query inspection with user-supplied authorization callbacks
- Streaming: Batch result streaming with minimal round trips
- Default Port: 9494 (94 = year Netscape Navigator launched)
Quack ships as a DuckDB extension (available in the core_nightly repository) and is included in DuckDB v1.5.2. It supports both TCP native connections and HTTP(S) tunnel mode, making it deployable behind reverse proxies like nginx.
Why DuckDB Needed a Client-Server Protocol
DuckDB's in-process architecture was always its superpower — and its limitation.
The upside: No separate server process, no protocol overhead, no configuration. Install DuckDB via pip, import it in Python, and you're running analytical queries in milliseconds. This is ideal for:
- Data science notebooks (Jupyter, VS Code)
- Embedded analytics in applications
- ETL pipelines and data wrangling scripts
- CLI tools and single-user workflows
The downside: Multiple processes can't safely write to the same database file at the same time. DuckDB keeps state in main memory — synchronizing that across processes is technically extremely difficult. The team explains this candidly on their blog.
The community built workarounds: custom RPC layers, Arrow Flight SQL adapters (like GizmoSQL), MotherDuck's proprietary protocol, and of course running DuckDB inside PostgreSQL (pg_duckdb). The sheer number of these workarounds convinced the DuckDB team that client-server support was something users genuinely needed.
"We see DuckDB as a universal data wrangling tool. If this means having a client-server protocol in addition to the in-process capabilities — fine. If this ends up unlocking a vast new set of use cases — excellent." — DuckDB Team
How to Use Quack: A 5-Minute Tutorial
Let's walk through the basic setup. You need two DuckDB instances — one acts as the server, the other as the client.
Step 1: Install the Quack Extension
Both instances need the Quack extension installed from the core_nightly repository:
INSTALL quack FROM core_nightly;
LOAD quack;
Step 2: Start the Server (DuckDB #1)
On the server machine (or terminal window), start the Quack listener:
INSTALL quack FROM core_nightly;
LOAD quack;
CALL quack_serve(
'quack:localhost',
token = 'super_secret'
);
CREATE TABLE hello AS
FROM VALUES ('world') v(s);
This starts a Quack server listening on localhost:9494 with an auth token super_secret.
Step 3: Connect from the Client (DuckDB #2)
INSTALL quack FROM core_nightly;
LOAD quack;
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
ATTACH 'quack:localhost' AS remote;
-- Query remote tables
FROM remote.hello;
Output: world. That's it — you've made your first remote DuckDB query via Quack.
Writing Data to a Remote Instance
Two-way operation works just as naturally. On the client side:
-- Client writes to remote
CREATE TABLE remote.hello2 AS
FROM VALUES ('world2') v(s);
Then the server can read it back:
-- Server reads
FROM hello2;
-- Output: world2
Running Remote Queries Explicitly
For complex queries on large datasets, you can ship exact SQL to the remote side:
FROM remote.query(
'SELECT s FROM hello'
);
This gives you fine-grained control over what executes where — crucial for optimizing hybrid query execution.
Quack Protocol Design
HTTP-Based Transport
Quack is built directly on HTTP. In 2026, this is a practical choice: HTTP is universally understood by load balancers, firewalls, intrusion detection systems, and reverse proxies. Every infrastructure engineer knows how to route, terminate, and secure HTTP traffic.
An unexpected bonus: the DuckDB-Wasm distribution can speak Quack natively. This means DuckDB running in a browser can directly connect to a DuckDB instance on an EC2 server using Quack over HTTP.
Request-Response Pattern
Interactions are client-driven with request-response semantics:
- Connection request: Authenticate with token
- Execute request: Submit SQL and receive the first batch of results
- Fetch requests: Retrieve additional rows (possibly in parallel from multiple threads)
Serialization
Requests and responses use the MIME type application/duckdb. The encoding leverages DuckDB's internal serialization primitives — the same ones used in the Write-Ahead Log (WAL) — which are well-optimized and battle-tested over years of production use.
Round-Trip Optimization
A connected query can be handled with a single round trip. This is critical for latency-sensitive environments. Bulk transfers are also heavily optimized — DuckDB claims Quack is currently "the fastest way to shove tables through a socket."
Authentication and Authorization
DuckDB's philosophy of extensibility extends to Quack's security model. Instead of trying to capture every use case, Quack provides a pluggable callback architecture:
Default Authentication
On startup, the Quack server generates a random token (or uses the one you provide via token = '...'). The default authentication callback compares the client-supplied token with the server's token.
Custom Authentication
You can replace the authentication callback with your own function. Examples:
- Query an LDAP directory
- Read a text file of valid tokens
- Roll dice (not recommended in production)
Custom Authorization
The default authorization function says "yes" to everything. But you can provide a callback that inspects each query, checks the authenticated identity, and decides per-query access. These callbacks can even be plain SQL macros.
Network Security
- By default, Quack binds to localhost only
- No SSL by default for localhost (avoids unnecessary TLS setup)
- For public exposure, DuckDB recommends an nginx reverse proxy with Let's Encrypt SSL
- Quack client auto-assumes SSL for non-local connections
Performance Benchmarks: Quack vs PostgreSQL vs Arrow Flight SQL
The DuckDB team ran benchmarks on AWS m8g.2xlarge instances (8 vCPUs, 32 GB RAM, up to 15 Gbps network, same availability zone, ~0.280 ms ping).
Bulk Transfer
They transferred TPC-H lineitem rows at increasing volumes, comparing Quack against PostgreSQL's wire protocol and Apache Arrow Flight SQL (via GizmoSQL, which also uses DuckDB internally). Results were measured as median wall clock time over 5 runs:
| Rows | Quack | PostgreSQL | Arrow Flight SQL |
|---|---|---|---|
| 6M rows | ~0.8s | ~2.5s | ~1.1s |
| 60M rows | ~4.2s | ~15s+ | ~5.8s |
Note: Numbers are approximate based on the blog post. Exact benchmark methodology is available in the original announcement.
Key findings:
- Quack significantly outperforms PostgreSQL for analytical bulk transfers — expected given DuckDB's columnar architecture designed for analytics
- Quack slightly exceeds Arrow Flight SQL, surprising since Arrow Flight is specifically designed for bulk columnar transfer
- The advantage grows with larger datasets, where DuckDB's efficient serialization and streaming architecture shine
Comparison: DuckDB Embedded vs DuckDB Quack vs PostgreSQL vs SQLite
| Dimension | DuckDB (Embedded) | DuckDB Quack | PostgreSQL | SQLite |
|---|---|---|---|---|
| Architecture | In-process | Client-Server | Client-Server | In-process |
| Query Focus | Analytics (OLAP) | Analytics (OLAP) | OLTP + Analytics | OLTP |
| Multi-writer | No | Yes | Yes | Limited |
| Setup Effort | Trivial (pip install) | 1 SQL command to start | Server install + config | Trivial |
| Protocol | C API only | Quack (HTTP/TCP) | PostgreSQL wire protocol | C API only |
| Bulk Transfer | N/A (in-process) | Excellent | Moderate | N/A (in-process) |
| Security | OS-level | mTLS + Auth callbacks | User/Password + SSL | None (file permissions) |
| Best For | Notebooks, local scripts | Remote analytics, pipelines | General-purpose, transactions | Local storage, mobile |
Use Cases for DuckDB Quack
Data Analytics Pipelines
Run DuckDB as a central analytics server. Multiple ETL processes write telemetry data. Dashboards query the same database concurrently. No more file-locking headaches.
Machine Learning Data Feeds
ML pipelines that fetch training data from DuckDB can now query a remote instance directly. Feature engineering scripts running on different machines can share a DuckDB server.
Remote Querying of Large Datasets
Instead of transferring 60M rows to your analysis machine, keep the data on the server and query it remotely. Quack's streaming protocol means you only pull what you need.
Multi-Service Architecture
In a microservices setup, one service can run DuckDB as a lightweight analytics backend. Other services query it via Quack without needing to embed DuckDB themselves.
Browser-Based Analytics
With DuckDB-Wasm supporting Quack, you can build browser-based analytics dashboards that query a remote DuckDB server directly — no backend middleware required.
How to Deploy Quack in Production
Option 1: Direct TCP (Local Network)
For same-machine or same-VPC communication, direct TCP with auto-generated tokens works out of the box. DuckDB binds to localhost by default, which is safe for internal traffic.
Option 2: HTTP(S) Tunnel with Reverse Proxy
For public or cross-network access, place nginx (or any HTTP reverse proxy) in front of Quack:
- Configure nginx to proxy
/quacktolocalhost:9494 - Terminate TLS with Let's Encrypt
- Add IP whitelisting or additional auth at the proxy layer
DuckDB provides official documentation for reverse proxy setup.
Option 3: WebSocket for Browser Clients
If your clients run DuckDB-Wasm in-browser, Quack over HTTP allows direct connections — no additional infrastructure needed.
FAQs
Is Quack ready for production?
Quack is available in DuckDB v1.5.2 as a core_nightly extension. The DuckDB team considers it stable for many workloads, but as with any 1.x protocol release, thorough testing is recommended for production deployments.
Does Quack replace the in-process architecture?
No. Quack is an addition, not a replacement. The in-process architecture remains DuckDB's primary mode for notebooks, scripts, and single-user applications. Quack is there when you need multi-process concurrent access or remote querying.
Can I use Quack with DuckDB's existing PostgreSQL protocol support?
Yes. DuckDB already supports the PostgreSQL wire protocol, allowing existing PostgreSQL clients and tools to connect. Quack is a separate, DuckDB-native protocol that offers better performance for DuckDB-specific workloads — especially bulk analytical transfers.
How does Quack compare to SQLite's lack of remote protocol?
SQLite famously has no remote protocol — you use file-based access. Workarounds exist (like sqlite3 over network filesystems, or projects like SQLiteServer), but they're not native. DuckDB now has both: the PostgreSQL wire protocol for compatibility and Quack for native high-performance remote access.
What authentication methods are supported?
Token-based auth is the default, but you can provide custom authentication and authorization callbacks. This means LDAP, OAuth, custom databases, or any other mechanism can be plugged in.
Conclusion
DuckDB Quack represents a thoughtful evolution of the embedded analytics database. The team didn't compromise on DuckDB's core identity — it's still the fastest way to get insights from data with minimal setup. But they recognized that "universal data wrangling tool" sometimes means running as a server.
The protocol design is pragmatic: HTTP-based for universal tooling compatibility, extensible auth for flexible deployment, and heavily optimized bulk transfers for the analytical workloads DuckDB excels at. The benchmarks against PostgreSQL and Arrow Flight SQL confirm that Quack is not just a compatibility feature — it's a performance story.
For teams already using DuckDB for data pipelines, ML workflows, and analytics, Quack removes the biggest architectural constraint: the single-process limitation. You can now think of DuckDB not just as a library you embed, but as a service you deploy.
And that opens up a lot of interesting possibilities.
References
DuckDB Blog: Quack — The DuckDB Client-Server Protocol
Hacker News Discussion (190 points)
DuckDB Quack Documentation
DuckDB Research Paper: Database Protocols
Tags: DuckDB, Quack Protocol, Client-Server, Analytics Database, Remote Protocol, Embedded Database, PostgreSQL, SQLite, Arrow Flight SQL, Benchmark, Database Architecture