QueryPilot
Frequently asked questions about QueryPilot, the Router, Accelerator, Guard, and Analytics.
MySQL support is in preview. MySQL proxying and MySQL CDC are functional and documented, but they are not part of the GA v1 support surface. PostgreSQL is the fully supported GA v1 path.
General
Do I need to change my application?
No code changes. Applications keep their drivers, SQL, and query patterns, and change only the host and port they connect to. One authentication detail: when a pool carries username/password (required for any network-facing listener), clients authenticate to the Router with those pool credentials. See Getting Started and Security.
How is QueryPilot licensed and distributed?
QueryPilot is a commercial product from Readyset, distributed as Docker images: querypilot (the Router), querypilot-analytics (Analytics), and querypilot-accelerator. Pre-release builds are published to public.ecr.aws/readyset; production releases go to Docker Hub. For access and licensing, contact hello@readyset.io. See Getting Started.
Do I need Readyset to use QueryPilot?
Only for the Accelerator, whose job is creating and managing caches on a Readyset deployment. The Router, Guard, and Analytics have no Readyset dependency. See the Accelerator guide.
Which components do I have to run?
Only the Router (binary querypilot). The Accelerator, Guard, and Analytics are each opt-in and independent of one another. See What is QueryPilot?.
Does the Router store my data?
No. The Router is a stateless proxy; it holds connections and in-memory statistics, not data. Analytics is the exception by design: it maintains a replicated copy of your selected tables in an on-disk DuckDB database. See the Analytics guide.
Compatibility
Which databases and versions are supported?
PostgreSQL is the GA v1 path, tested against PostgreSQL 15 and 16, for both proxying and CDC into Analytics (CDC requires wal_level = logical on the source). MySQL proxying and MySQL CDC are in preview, tested against MySQL 8.0 (CDC requires GTID mode). See the compatibility table in What is QueryPilot?.
Does the Router terminate TLS?
No. In the current release the Router handles client and backend connections in plaintext. Run it on a trusted network segment, bind listeners to loopback or private addresses, and terminate TLS in front of it (load balancer, mTLS sidecar, VPN) when clients connect over untrusted networks. See Security.
Can MySQL clients query PostgreSQL backends?
Yes. Setting protocol on a pool forces the backend wire protocol regardless of what the client speaks; the Router decodes result rows from the backend protocol and re-encodes them for the client. This is how MySQL clients are served from Analytics, which speaks PostgreSQL wire. See the Router guide.
How do prepared statements work through the Router?
Prepared statements are supported on both protocols, including the PostgreSQL extended protocol with binary encoding, and are exercised continuously by client-framework tests (pgx, psycopg3, PyMySQL, and others). For vanilla PostgreSQL-to-PostgreSQL pools, raw_passthrough streams prepared-statement results to the client without re-encoding; leave it off for cross-protocol pools. See the Router guide.
What SQL dialect does Analytics speak?
DuckDB's. It is close to PostgreSQL for typical analytics but not identical, and MySQL-origin queries often need rewriting. The Router's translation rules rewrite specific query shapes on the way in, for example MySQL JSON_OVERLAPS(...) into DuckDB list_has_any(...). See the Analytics guide and the Router guide.
Operations
How do I see where a query routes?
GET /api/routing/test?sql=... on the admin API dry-runs the routing decision without sending traffic and returns the target pool, the matched rule, and the query's fingerprint hash. Under load, sqp_routing_decisions_total counts decisions by type and target pool. See the read/write splitting tutorial.
What happens when a backend goes down?
Health checks mark the backend unavailable and new connections skip it; backends within a pool are opened round-robin across the healthy set. A replica whose measured lag exceeds its max_replica_lag is treated the same way. Recovered backends rejoin automatically. Sessions that cannot get a connection within acquire_timeout receive an error rather than queueing forever. See Operations.
Does enabling plugins slow queries down?
Not until you enable one. With no plugin blocks configured, the plugin chain is empty and adds zero per-query overhead. Guard, when enabled, evaluates under a per-decision latency budget (default 50 ms cap, fail-open for reads); the Accelerator does its work on a background thread, not in the query path. See Performance.
How do I monitor QueryPilot?
Enable [metrics] and both the Router and Analytics serve Prometheus metrics under the sqp_ prefix (Router convention: metrics on 9090, admin API always on metrics port + 1). Start with sqp_query_duration_seconds, sqp_pool_acquire_duration_seconds, sqp_routing_decisions_total, and sqp_duckdb_replication_lag_seconds. See the metrics reference and Operations.
How do I change configuration safely?
Validate first: querypilot --check -c querypilot.toml (the Router's schema is strict and rejects unknown keys), then POST /api/config/reload on the admin API applies routing and translation changes without a restart. Analytics has the same --check flag but boots on defaults if its config file is missing, so always verify the path. See the router configuration reference and analytics configuration reference.
Components
How fresh is Analytics data?
Analytics applies changes continuously from the source's replication stream; after the initial snapshot, freshness is the CDC apply lag, typically seconds under normal operation. It is exported as sqp_duckdb_replication_lag_seconds, and GET /api/status shows the stream position. Alert on the lag metric in production. See the Analytics guide and the HTAP tutorial.
What happens to Analytics data across restarts?
It persists. Replicated data and the replication checkpoint are committed together in DuckDB, so a restart resumes streaming exactly where the committed state left off, and a crash never leaves half-applied batches. A missing checkpoint (fresh database) triggers a full snapshot. See the Analytics guide.
Can Analytics handle schema changes?
Partially. ALTER TABLE ... ADD COLUMN replicates through the change stream (with NOT NULL/DEFAULT constraints dropped); DROP, MODIFY, and RENAME COLUMN do not, and should be planned as re-snapshot events: remove and re-add the table through the API, or restart with a clean database file. See the Analytics guide.
What can Guard actually do to a query?
The shipped decision set: allow it, block it with a structured error, amend it (add_limit, add_timeout, force_read_only), or reroute it to a different pool. Enforcement can be staged through shadow and warn modes before anything bites, and every decision is audited. See the Guard tutorial.
What does the Accelerator do if Readyset goes down?
It fails safe. The health-check stage detects the outage, disables the routing rules the plugin owns so traffic flows to the source database, and re-enables them when Readyset recovers. Runtime errors in the plugin never affect query traffic. See the Accelerator guide.