Skip to main content
DuckDB control plane

Autoscale DuckDB fleets
on demand.

From a single Docker container on one node to fleets of DuckDB Quack nodes on your own Kubernetes. Per-tenant isolation, fine-grained ACLs, federated queries. Query it from any ODBC/JDBC/ADBC client, orATTACH it straight from DuckDB. Works with any ETL.

uvx qod start --demo no install, no Postgres

client.py
# One endpoint, JDBC / ADBC / ODBC / PyArrow
conn = flight_sql.connect(
    "grpc+tls://gateway:31338",
    db_kwargs={
      "username": "alice", "password": "•••",
      tenant: "acme", pool: "analytics"})

# routed to the least-loaded node for the tenant
cur = conn.cursor()
cur.execute("SELECT count(*) FROM orders")
cur.fetchone()
(1500000,)

From a single database to a fleet

uvx qod start
$ uvx qod start
control-plane Postgres: jdbc:postgresql://localhost:5432/qod (user postgres)
 Quack on Demand 0.5.0 is up
   control plane : jdbc:postgresql://localhost:5432/qod
   REST API + UI : http://localhost:20900  (UI: http://localhost:20900/ui)
   FlightSQL     : grpc+tls://localhost:31338
   Quack (DuckDB): quack:localhost:9494  (plain HTTP)

 Client connection strings (replace <tenant>, <pool>, <user>):
   DuckDB: ATTACH 'quack:localhost:9494' AS qod (TYPE quack, TOKEN 'tenant=<tenant>&pool=<pool>&user=<user>&password=<password>');
   JDBC : jdbc:arrow-flight-sql://localhost:31338/?tenant=<tenant>&pool=<pool>&user=<user>&useEncryption=true&disableCertificateVerification=true
   ADBC : uri=grpc+tls://localhost:31338  (adbc_driver_flightsql)
   ODBC : Driver={Arrow Flight SQL ODBC Driver};Host=localhost;Port=31338;...

From zero to SQL in one command

One command boots the whole platform: manager, FlightSQL endpoint, native Quack front door, admin UI, and demo data. No cluster, no YAML, no prerequisites beyond Python and a JVM.

The boot banner hands you working JDBC, ADBC, and ODBC connection strings and a ready-to-paste DuckDB ATTACH. Paste one into your tool and you are querying.

qod sql
qod> SELECT o_orderpriority, count(*) FROM orders GROUP BY 1 ORDER BY 1;
+-----------------+----------+
| o_orderpriority | count(*) |
+-----------------+----------+
| 1-URGENT        |    30044 |
| 2-HIGH          |    30076 |
| 3-MEDIUM        |    29949 |
+-----------------+----------+
3 rows in 0.04s

Talk to it from anything that speaks SQL

Two wires, one gateway. Arrow FlightSQL serves the driver estate: JDBC and ODBC for BI tools, ADBC and Python for notebooks, the qod CLI for your terminal. DuckDB's own Quack protocol serves DuckDB itself, so a laptop, a notebook, or an embedded engine runs ATTACH 'quack:host:9494' and joins local tables with governed shared ones, no driver to install.

Both land in the same path: same identity, same per-statement ACL, same audit log. Statements are classified read or write and routed to the least-loaded node that can serve them, with transaction pinning.

Tenants, pools, and a hibernated pool one click from waking.

A real multi-tenant control plane

Tenants own databases, users, and pools of DuckDB nodes, isolated by storage layout and access control.

Idle pools suspend to zero nodes and keep their catalogs; the first query wakes them automatically. You pay for compute only while queries run.

alice (analyst) $ SELECT c_phone, c_mktsegment FROM customer
c_phonec_mktsegment
***BUILDING
***BUILDING
***BUILDING
admin $ SELECT c_phone, c_mktsegment FROM customer
c_phonec_mktsegment
25-989-741-2988BUILDING
23-768-687-3665AUTOMOBILE
13-761-547-5974MACHINERY

Every user sees only their data

The same query, two users, two answers: that is the access-control model working.

Tenant isolation at the edge, per-table grants (read, write, DDL), row-level security filters, and column masking are all enforced before a statement ever reaches a node.

Every write is a snapshot: browse, tag, diff, restore.

Your data has an undo button

DuckLake gives every table a history: time-travel reads, named tags, undrop for deleted tables, and restore that rolls back as a new snapshot with nothing lost.

Mistakes stop being incidents and become queries.

Per-statement history, audit trail, usage trends.

See everything

Per-statement history with latency and routing, a full audit trail, usage trends per tenant, and Prometheus metrics for your dashboards.

One containeruvx qod startembedded demo dataOne nodeyour Postgres catalogyour S3 or diskKubernetespools of pods, HA managersscale-to-zero tenants

Start on a laptop. Grow to a cluster.

The single-container mode is first-class, not a demo: run it on one box for years if that is all you need.

When you outgrow it, point the same gateway at your Postgres and object store, then move to Kubernetes with pools of pods and HA managers. Your clients never notice: same endpoint, same tenants, same SQL.

Which setup do you need?

CapabilityPlain DuckDBqod serve on filesqod serve + Icebergqod serve on DuckLake
Access
Arrow Flight SQL endpoint (BI tools, ODBC, JDBC, ADBC)✓✓✓
Native Quack protocol (ATTACH straight from DuckDB)✓✓✓
MCP server for AI agents✓✓✓
Security
TLS and authentication✓✓✓
RBAC on tables, columns and rows✓✓✓
Encryption at rest for Parquet and database files✓✓✓
Data
Serve DuckDB files, parquet, csv, S3 prefixes✓✓✓
Iceberg REST catalog federation✓✓
DuckLake warehouse on Postgres and object storage✓
History
Time travel and snapshot tags✓
Undrop and rollback✓
Author stamping and audit timeline✓
Operations
Multi-tenant isolation✓✓✓
Multi-node routing✓✓✓
Kubernetes deployment✓✓✓
Compaction and cleanup policies✓
Sovereignty
Runs fully in your infrastructure✓✓✓✓

Plain DuckDB can read these formats locally. This table shows what is served to others.

Reach for it when sharing matters.

Many users on shared DuckDB/DuckLake data, access control on every query, horizontal scale, tenant isolation, or federation. Querying one local file? Use DuckDB directly.

Looking for one answer? The DuckDB how-tos cover access control, single sign-on, ADBC and multi-tenancy.