Deploy

Deploy it your way

Every way of running QueryAPIGate uses the same server; the shapes differ only in which parts you add around it. Start with one container and a file on disk. Add PostgreSQL and Redis when you need more than one instance, and add the Rust data plane and a ClickHouse run store when traffic calls for it. You don't rewrite anything or move your queries, and your API keys and URLs stay the same.

Install options Deployment guide
pip · Docker · Helm·Signed image and chart·Non-root, read-only root filesystem·Three real servers on one shared store, on every push
pippip install "queryapigate[server]", then gunicorn with one worker. Add drivers as extras: postgres, mysql, clickhouse, h2, redis, or all.
Dockerghcr.io/anantharajuc/queryapigate:0.47.0 includes every driver, JWT, the Redis cache and queryapigate mcp. The -h2 tag adds Java, for H2 and generic JDBC.
Helmoci://ghcr.io/anantharajuc/charts/queryapigate --version 0.47.0. The chart version always matches the server version.
SignedEvery image and chart since 0.31 is signed keyless with cosign by the release workflow, with SLSA provenance and an SBOM.
One server, nine parts

The building blocks

One server, and the parts you add around it as you need them. The experimental parts are outside the compatibility promise.

API serverStable

Serves your saved queries as REST endpoints, plus the Console, the admin API and /docs.

WhenAlways
Metadata storeSQLiteStable

Holds connections, queries, keys, roles, history and the audit log in one file.

WhenOne instance; the default
Metadata storePostgreSQLStable

The same data in a database you already back up.

WhenSeveral instances, or managed backups
RedisStable

Shares rate limits and the response cache across instances, and keeps the cache through restarts.

WhenRequired for several instances; optional for one
Events serverqueryapigate eventsStable

Streams live events to many apps and phones at once.

WhenMany live-event clients
MCP serverqueryapigate mcpStable

Gives AI agents your saved queries as tools, under the same keys, roles and audit log.

WhenAI-agent access
Rust data planeExp

Serves saved-query reads at 3–9× the calls per second per core.

WhenHigh-traffic read endpoints
ClickHouse run storeExp

Keeps run history and the event log, to billions of rows a day.

WhenData-plane-scale traffic
Reverse proxyor load balancerYour choice

TLS, and spreading requests across instances. A Caddy example is included.

WhenProduction

Three reference architectures, each tested in CI

All three run the same image and the same code. Each is exercised on every change: three real servers sharing one store, and the chart installed and upgraded under load on a real cluster.

On every push:CI workflow statusPublish Docker image workflow status
Apps · partners · agentsReverse proxyTLSQueryAPIGate:5000 REST · Console · :5001 MCPrestarting…Your databasesStoreSQLite on a volume
01…
Start here

Single instance

✓One container or process; SQLite store on a volume, or PostgreSQL.
✓Restart on failure; back up the store on a schedule.
✓Redis optional, for a cache that survives restarts.
StoreSQLite on a volume, or PostgreSQL
RedisOptional
Live eventsGET /events on the instance
AvailabilityRestart on failure
ConfigurationEnvironment, Console or a file
Tested in CIEvery push
Apps · partners · agentsLoad balancerCaddy · health checksInstance:5000Instance:5000unhealthy · skippedEvents:5002PostgreSQLshared storeRedislimits · cacheYour databases
01…
Several instances

High availability

✓PostgreSQL store and Redis: everything an instance owns is shared, so any instance answers any request.
✓Rate limits, quotas and concurrency caps counted across instances.
✓Rolling upgrades; queryapigate events fans live events out to many clients.
StorePostgreSQL
RedisRequired
Live eventsqueryapigate events, routed by the proxy
AvailabilityThe load balancer skips an unhealthy instance
ConfigurationEnvironment, Console or a file
Tested in CIThree real servers, every push
Ingress/events and MCP routedDeploymentrolling update · PDBEvents · MCPown podsSecret or VaultexistingSecretServiceMonitortoken-protected /metricsPostgreSQL · RedisYour databases
01…
Helm chart

Kubernetes

✓One pod on SQLite, or several on PostgreSQL and Redis behind a disruption budget.
✓Non-root, read-only root filesystem, no capabilities; a NetworkPolicy and autoscaler if you want them.
✓The chart refuses setups that can't work, such as several pods without Redis.
StoreSQLite (one pod) or PostgreSQL
RedisRequired for more than one pod
Live eventsEvents pods, routed by the ingress
AvailabilityRolling updates, disruption budget
Configurationconfig values, configAsCode
Tested in CIkind cluster: install, upgrade under load
Six shapes, three add-ons

Choose your shape

The three above, and the parts you can add to any of them. Moving between shapes is a configuration change: what each step adds is below.

Try it

API server + SQLite

Running it on your laptop in a minute.

Start with
pip install "queryapigate[server]" or docker compose up for the demo

Single server

API server + SQLite on a volume + reverse proxy (+ Redis for the cache)

Small teams and internal tools.

Start with
The Docker image and the production Compose guide

Single server, managed store

API server + PostgreSQL store + reverse proxy

Keeping state in a database your team already runs and backs up.

Start with
One setting: QUERYAPIGATE_DATABASE_URL

Scaled out

2+ API servers + PostgreSQL + Redis + events server + load balancer

High availability and more capacity on plain Docker.

Start with
deploy/scale-out/, one Compose file

Kubernetes, one pod

Helm chart, store.type: sqlite, a PersistentVolumeClaim

A small cluster deployment.

Start with
helm install … oci://ghcr.io/anantharajuc/charts/queryapigate

Kubernetes, highly available

Helm chart, store.type: postgres, several replicas + Redis

Production clusters: rolling upgrades, autoscaling, a PodDisruptionBudget.

Start with
The same chart, replicas: 3
Add to any shape

+ AI agents

Any shape above + MCP server

Governed data access for agents: Claude, IDEs, custom agents.

Start with
A second container, or mcp.enabled: true in Helm

+ High throughput

Exp
Any shape + the Rust data plane in front of each API server

Hot read endpoints at tens of thousands of calls a second.

Start with
dataplane.enabled: true in Helm, or deploy/scale-out/docker-compose.dataplane.yml; guide 64

+ Very high volume

Exp
Data plane + ClickHouse run store

Every call still recorded, at billions of runs a day.

Start with
QUERYAPIGATE_RUN_STORE_URL
What each shape needs required optional — not used
Try itSingle serverScaled outKubernetes HAHigh volume
API server112+2+ pods2+
SQLite store———
PostgreSQL store—
Redis—
Events server—
MCP server
Rust data plane—
ClickHouse run store——
Reverse proxy—load balancerIngress
What changes when you move
01Single instance
QUERYAPIGATE_API_KEY=… QUERYAPIGATE_SECRET_KEY=… One process or container, with the store as SQLite on a volume. The key is required in a container; the secret key encrypts connection passwords at rest.
02+ High availability
QUERYAPIGATE_DATABASE_URL=postgres://… QUERYAPIGATE_REDIS_URL=redis://… A shared PostgreSQL store and Redis, so any instance answers any request and limits are counted once. Run queryapigate events behind the proxy for live events. Guide 42 →
03+ Kubernetes
store.type: postgres · replicas: 3 existingSecret: queryapigate The same two URLs and the key live in one Secret; the chart refuses several pods on SQLite, several without Redis, PostgreSQL without a database URL, and secrets put in config. Guide 54 →
In every shape

Works with every shape

Prometheus metrics and a Grafana dashboard, plus OpenTelemetry tracing Exp.

Secrets from Vault or AWS Secrets Manager Exp, and short-lived database credentials.

Signed-in users through JWT and SSO, as well as API keys.

Configuration as code: connections, queries, roles and keys in one file in git Stable.

Hardened by default: runs as non-root, on a read-only root filesystem, with every capability dropped.

Helm chart

Guardrails, not surprises

The Helm chart refuses to install a shape that would quietly misbehave, and says why in its own words:

helm install · what the chart refuses
replicas: 3 · store.type: sqlitestore.type sqlite keeps the store in one file on one volume - it runs one pod.
replicas: 3 · no RedisMore than one pod needs Redis, or rate limits, max_concurrent and quotas are counted per pod.
store.type: postgres · no database URLstore.type postgres needs QUERYAPIGATE_DATABASE_URL in secret.values (or in your existingSecret).
config: · QUERYAPIGATE_API_KEYQUERYAPIGATE_API_KEY is a secret: put it in your existingSecret or secret.values, not config - config is plain text in the Deployment.
You find out at helm install, before anything changes in your cluster.
Before go-live

Production checklist

The steps between a running server and one you would put in front of a partner. Tick them off as you go; this browser remembers.

{{ ckDone }} of 8 done
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07
  8. 08