Quack on Demand: multi-tenant SQL gateway for DuckDB and DuckLake
Quack on Demand is a multi-tenant SQL gateway for DuckDB and DuckLake. It puts a single, governed, horizontally-scaled SQL endpoint in front of many DuckDB engines that share DuckLake catalogs, so a fast embedded database becomes a service that teams and applications can query together.
It serves two wires from that one endpoint: Arrow Flight SQL for the JDBC / ODBC / ADBC estate, and DuckDB's own Quack protocol, so any DuckDB carrying the quack extension can ATTACH the gateway as a database with no driver in between.
What it does
Clients speak Arrow Flight SQL or the native Quack protocol to the gateway. Either way, it authenticates the connection, authorizes every statement against a role-based access model, classifies it read or write, and routes it to the least-loaded DuckDB node that can serve it (on object-store pools, biased toward a node that already has the query's tables cached). The nodes read and write Parquet through shared DuckLake catalogs, so they present one consistent view and a pool can scale out across many of them.
The two wires are two front doors to the same gateway, not two products: same tenants, same users, same per-statement ACL, column masking and row filters, same router, same audit log. Only the wire differs.
In other words, it adds the things a single embedded DuckDB does not have on its own: multi-tenancy, authentication and per-statement access control, horizontal scale, and a stable client endpoint, without replacing DuckDB as the engine.
Why it exists
DuckDB is excellent for fast analytics, and DuckLake gives it a durable, object-store-backed catalog. But on their own they are single-process: there is no shared endpoint, no notion of tenants or users, no access control on a query, and no way to spread load across nodes. Teams that want to expose DuckDB/DuckLake data to many users or applications end up rebuilding the same gateway concerns each time. Quack on Demand is that gateway, built once: connection management, identity, authorization, routing, failover, and observability around the engine you already use.
When to use it
Reach for Quack on Demand when you want to:
- Serve many users or applications from shared DuckDB/DuckLake data through one governed endpoint, instead of handing out database files.
- Enforce access control on every query: role-based, per-table permissions with tenant isolation, applied before a statement touches a node.
- Scale horizontally: spread read and write traffic across a pool of DuckDB nodes over a single shared catalog, with least-loaded routing (cache-aware on object-store pools) and retry on failure.
- Isolate tenants: keep each tenant's databases, users, and compute separate, with its own auth provider.
- Federate external sources (Postgres, S3 / Iceberg, anything DuckDB can attach) behind the same SQL surface and the same access model.
- Keep the clients you already have: Arrow Flight SQL covers JDBC, ADBC, ODBC, PyArrow, DBeaver, and Spark, which all connect the same way.
- Attach the gateway from DuckDB itself over DuckDB's native Quack protocol (
ATTACH 'quack:host:9494' AS qod), so a laptop DuckDB, a notebook, or an embedded engine joins its local tables with governed shared tables in one query, with no driver to install. See DuckDB (native Quack). - Give AI agents governed data access: an embedded MCP server lets agents such as Claude Code discover schemas and run SQL with the same per-statement access control as any other client.
When not to use it
It is the wrong tool when:
- One user or app queries a local DuckDB file. Use DuckDB directly. The gateway adds operational machinery (a manager, Postgres, pools) that only pays off when you need sharing, isolation, or scale.
- You do not need multi-tenancy, access control, or horizontal scale. If none of the reasons above apply, the gateway is overhead.
- You need OLTP semantics or cross-node transactions. This is an analytical query gateway: transactions pin to a single node, and it is not a substitute for a transactional database.
- You need engine features DuckDB does not have. The gateway executes DuckDB SQL; it routes and governs queries, it does not extend the engine.
What is inside
| Capability | In short |
|---|---|
| Client protocols | Arrow Flight SQL (:31338) and DuckDB's native Quack protocol (:9494), one identity and policy model behind both |
| Multi-tenancy | Tenants own databases (DuckLake catalogs) and pools of DuckDB nodes |
| Access control | Authentication (database, JWT, OIDC) plus role-based, per-statement table ACL |
| Routing | Statement classification, least-loaded node selection (cache-aware on object-store pools), transaction pinning, retry-once |
| Storage | DuckLake catalogs over a filesystem or S3-compatible object store |
| Federation | Attach external catalogs (Postgres, S3/Iceberg) under the same ACL |
| AI agents | Embedded MCP server with personal-access-token auth; every tool call goes through the same RBAC |
| Operations | Prometheus / cloud metrics, a config manifest for backup and restore, an admin UI |
| Deployment | A single Docker container on one node (ideal for a single tenant), or Kubernetes for multi-host fleets and manager HA |
Looking for something specific?
The DuckDB how-tos answer the questions people arrive with, one page each: access control, authentication, single sign-on, ADBC, a Flight SQL server and multi-tenancy.
Where to go next
- Quickstart - from zero to your first query.
- Architecture - how the pieces fit and how a request flows.
- Connecting clients - JDBC, ADBC, ODBC, and DuckDB's own
ATTACH. - Operating - deploy, provision tenants and pools, govern access.
Questions or feedback? Join the community on Discord or open an issue on GitHub.
QoD and Starflow
QoD is a standalone product; you do not need Starflow to run it. If you use Starflow, the starlake quack command can host a Quack DuckDB server inside the Starflow process for local, single-node use, and Starflow can query a QoD fleet as a regular connection, over either wire: ATTACH 'quack:host:9494' from its DuckDB engine, or a Flight SQL driver. For multi-tenant fleets with autoscaling and ACLs, use QoD.