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
# 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,)$ 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;...
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> 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
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 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.
| c_phone | c_mktsegment |
|---|---|
| *** | BUILDING |
| *** | BUILDING |
| *** | BUILDING |
| c_phone | c_mktsegment |
|---|---|
| 25-989-741-2988 | BUILDING |
| 23-768-687-3665 | AUTOMOBILE |
| 13-761-547-5974 | MACHINERY |
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.
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 with latency and routing, a full audit trail, usage trends per tenant, and Prometheus metrics for your dashboards.
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.
| Capability | Plain DuckDB | qod serve on files | qod serve + Iceberg | qod 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.
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.