Skip to main content
Arrow Flight SQL gateway

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. Works with any ETL.

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

 Client connection strings (replace <tenant>, <pool>, <user>):
   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, 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. 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

One Arrow FlightSQL endpoint serves every client: JDBC and ODBC for BI tools, ADBC and Python for notebooks, the qod CLI for your terminal.

Statements are classified read or write and routed to the least-loaded node that can serve them, with transaction pinning, behind that single endpoint.

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.

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.