# Quack on Demand: multi-tenant SQL gateway for DuckDB and DuckLake

> Quack on Demand puts an authenticated, access-controlled, autoscaled SQL endpoint in front of DuckDB and DuckLake, over Flight SQL or native ATTACH.

**Quack on Demand** is a multi-tenant SQL gateway for [DuckDB](https://duckdb.org) and [DuckLake](https://ducklake.select). 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](https://arrow.apache.org/docs/format/FlightSql.html) 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)](/qod/connecting/duckdb).
- **Give AI agents governed data access**: an embedded [MCP server](/qod/connecting/mcp) 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](/qod/duckdb) answer the questions people arrive with, one page each: [access control](/qod/duckdb/access-control), [authentication](/qod/duckdb/authentication), [single sign-on](/qod/duckdb/sso), [ADBC](/qod/duckdb/adbc), [a Flight SQL server](/qod/duckdb/flight-sql-server) and [multi-tenancy](/qod/duckdb/multi-tenant).

## Where to go next

- **[Quickstart](/qod/getting-started/quickstart)** - from zero to your first query.
- **[Architecture](/qod/concepts/architecture)** - how the pieces fit and how a request flows.
- **[Connecting clients](/qod/connecting/clients)** - JDBC, ADBC, ODBC, and DuckDB's own `ATTACH`.
- **[Operating](/qod/operating/deploy-local)** - deploy, provision tenants and pools, govern access.

Questions or feedback? Join the [community on Discord](https://discord.gg/xHj9D6Rebp) or open an issue on [GitHub](https://github.com/starlake-ai/quack-on-demand).

## QoD and Starflow

QoD is a standalone product; you do not need Starflow to run it. If you use Starflow, the [`starlake quack`](/starflow/cli/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](/starflow/guides/project-setup/connections), 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.
