Skip to content
QueryPilot
Early preview · v0.1Open source soon · Apache-2.0

Postgres got slow at 14:32.Here’s why.

QueryPilot watches your queries, plans, locks and tables. When something changes, it finds the cause, gives you the SQL to fix it, and then checks that the fix actually worked.

  • Self-hosted
  • Read-only by construction
  • Nothing leaves your network
orders-primaryproduction live

Mean latency

1.8 ms38 ms 21×1.7 ms

SELECT … FROM orders WHERE customer_id = $1
HighPlan regression detected

Index Scan → Seq Scan on orders

Cause: statistics are stale. 4.1M rows changed since the last ANALYZE.

VerifiedFix applied and measured

ANALYZE orders;

p95 went from 84 ms to 5 ms. The before/after difference is statistically significant.

Sample data. The flow matches the real product.
writes to your database
0
writes to your database
connections, at most
2
connections, at most
detection rules built in
16
detection rules built in
PostgreSQL versions supported
12+
PostgreSQL versions supported

The problem

PostgreSQL remembers totals. Incidents happen in minutes.

pg_stat_statements adds everything up since the last reset. It cannot tell you what got slower this afternoon, and nobody saved the plan that used to work.

pg_stat_statements on its own

total_exec_time since the last reset

A running total. The incident is a slight change of slope on a line that only ever goes up.

With QueryPilot

Execution time per minute

Snapshots turned into deltas. The same 10 minutes stand out immediately, with a start, an end and a cost.

Inside the app

Every database, live, on one screen.

Throughput, latency, cache and connections at a glance. The queries that cost the most rise to the top, and new findings arrive as they are detected.

orders-primary

productioncheckoutLast 1 hour · live
Calls / min
18,420
+3.1%
Mean latency
4.2 ms
−0.4 ms
Cache hit
99.4%
healthy
Active connections
37
of 200
Mean latency (ms) all queries
Top queries by total time
  • SELECT … FROM orders WHERE customer_id = $130%
  • UPDATE inventory SET reserved = reserved + $1 …27%
  • SELECT … FROM order_items WHERE order_id = $123%
  • INSERT INTO events (type, payload, …) VALUES …11%
  • SELECT count(*) FROM invoices WHERE account_id = $110%
HighNew finding · just now

Plan regression on orders by customer

Index Scan → Seq Scan after 4.1M rows changed.

Sample data, animated. The real interface is in the live demo.

What it catches

The 3 a.m. problems, explained before you open psql.

Five things that take production Postgres down every day, and what QueryPilot shows you for each.

A bulk load flips the plan of your hottest query

Mean latency (ms)last 24 hours

Reads: pg_stat_statements · EXPLAIN (GENERIC_PLAN) · pg_stat_user_tables

  1. Detect

    Mean latency is 19× its baseline since 14:32. Calls per minute did not change, so this is not extra traffic.

  2. Explain

    The planner switched from Index Scan to Seq Scan on orders. 4.1M rows changed since the last ANALYZE.

  3. Fix

    ANALYZE orders;
  4. Outcome

    p95 went from 84 ms to 5 ms, measured over matching windows before and after.

Sample data. Each scenario comes from a detection rule QueryPilot runs today.

How it works

From raw statistics to a verified fix.

Every step is deterministic and inspectable. No model guesses at your data, and nothing runs against your database without you.

  1. 1

    Collect

    Snapshots of query stats, activity, locks, wait events and table health every few seconds.

    pg_stat_statements · pg_stat_activity · pg_locks · catalogs

  2. 2

    Detect

    Detection rules compare each window with its history: regressions, lock storms, bloat, N+1, invalid indexes.

    deterministic rules, no black box

  3. 3

    Explain

    Every finding carries its evidence: the plan diff, the blocking chain, the stale statistics.

    plan fingerprints · wait profiles

  4. 4

    Recommend

    A concrete fix with the SQL to run: an index, ANALYZE, a vacuum setting, a batched query.

    you apply it, QueryPilot never writes

  5. 5

    Validate

    Before and after windows are compared statistically, so "it feels faster" becomes "improved" or "regressed".

    Welch's t-test on latency

Features

See it, understand it, fix it.

01 · See

Everything PostgreSQL knows, kept over time.

  • Query history

    Per-query latency, calls, rows and I/O rebuilt from pg_stat_statements deltas, for any window.

  • Plan capture & diff

    Plans fingerprinted by shape. See the exact node that changed, like Index Scan to Seq Scan.

  • Waits & locks

    Sampled wait events per query, plus blocking chains with the session at the root.

  • Table & index health

    Dead rows against the real autovacuum threshold, freeze age, unused and invalid indexes.

02 · Understand

Findings with evidence, not dashboards to stare at.

  • Regression detection

    Latency compared against each query’s own history, tied to the plan change that caused it.

  • N+1 detection

    Child queries whose call rate tracks a parent query’s rows, found from statistics alone.

  • Severity & evidence

    Every finding explains itself: which numbers, which window, which rule, and why it matters.

  • Environments & tags

    Group databases by production, staging or your own tags, and filter everything by them.

03 · Fix

The SQL to run, and proof it worked.

  • Index advice

    Missing, duplicate and unused indexes, with CREATE INDEX CONCURRENTLY or DROP INDEX ready to copy.

  • Maintenance advice

    ANALYZE for stale statistics, autovacuum settings for tables that fall behind.

  • Query rewrites

    Batching suggestions for N+1 patterns, with the query shape to use instead.

  • Fix validation

    Before and after windows compared with a significance test: improved, no change or regressed.

Built for production

Safe to point at the database that pays the bills.

A small agent next to Postgres reads statistics and pushes them out over HTTPS. Everything else runs on your servers, on a plain PostgreSQL you already know how to operate.

Read the architecture guide →
QueryPilot architectureThe agent runs in your infrastructure next to the observed PostgreSQL database, reads statistics read-only, and sends telemetry outbound over HTTPS to the QueryPilot API. The API stores data in QueryPilot's own PostgreSQL, which the worker also uses for analysis, validation and its job queue. The web app reads everything through the API.Your infrastructureQueryPilot (self-hosted)PostgreSQLyour database · pg_stat_statementsAgentcollectors · bounded bufferplan capture · task runnerread-only SQL2 connections · timeoutsAPINestJS · /api/v1ingestion · findings · plansHTTPSoutbound onlyWebNext.js UIoverview · queries · plansRESTWorkeranalysis · validation · jobsPostgreSQLQueryPilot storageTypeORM
QueryPilot architectureThe agent runs in your infrastructure next to the observed PostgreSQL database, reads statistics read-only, and sends telemetry outbound over HTTPS to the QueryPilot API. The API stores data in QueryPilot's own PostgreSQL, which the worker also uses for analysis, validation and its job queue. The web app reads everything through the API.Your infrastructureQueryPilot (self-hosted)PostgreSQLyour database · pg_stat_statementsread-only SQL2 connections · timeoutsAgentcollectors · bounded bufferplan capture · task runnerHTTPSoutbound onlyAPINestJS · /api/v1ingestion · findings · plansRESTWebNext.js UIqueries · plansWorkeranalysisvalidation · jobsTypeORMPostgreSQLQueryPilot storage
QueryPilot architecture
QueryPilot architectureThe agent runs in your infrastructure next to the observed PostgreSQL database, reads statistics read-only, and sends telemetry outbound over HTTPS to the QueryPilot API. The API stores data in QueryPilot's own PostgreSQL, which the worker also uses for analysis, validation and its job queue. The web app reads everything through the API.Your infrastructureQueryPilot (self-hosted)PostgreSQLyour database · pg_stat_statementsAgentcollectors · bounded bufferplan capture · task runnerread-only SQL2 connections · timeoutsAPINestJS · /api/v1ingestion · findings · plansHTTPSoutbound onlyWebNext.js UIoverview · queries · plansRESTWorkeranalysis · validation · jobsPostgreSQLQueryPilot storageTypeORM

Scroll or pinch to explore. Press Esc to close.

  • Read-only sessions

    default_transaction_read_only=on, so PostgreSQL itself rejects any write.

  • Plans never execute

    EXPLAIN (GENERIC_PLAN) inside a transaction that is rolled back.

  • Bounded by design

    Two connections, row caps and statement timeouts on every collector.

  • Outbound-only agent

    No inbound ports to open next to your database.

  • Credentials encrypted

    AES-256-GCM at rest and never returned by the API.

  • No parameters stored

    Query text is normalized, and you can turn text collection off entirely.

Quickstart

Running in three steps.

  1. 1

    Run QueryPilot

    One Docker Compose file: web, API, worker and storage.

  2. 2

    Connect a database

    A least-privilege role with pg_read_all_stats.

  3. 3

    Start the agent

    Next to your database. Data arrives within seconds.

Needs Docker and PostgreSQL 12+ with pg_stat_statements. Plan capture needs 16+.

QueryPilot is in early preview. The repository and these commands become available when the source is published.

# The repository becomes available at launch
cd querypilot && cp .env.example .env
sed -i.bak "s|^QUERYPILOT_ENCRYPTION_KEY=.*|QUERYPILOT_ENCRYPTION_KEY=$(openssl rand -base64 32)|" .env
docker compose up -d --build
# open http://localhost:3000

Roadmap

Where QueryPilot is going.

Detection, recommendations and validation are built. Next, QueryPilot comes to where your team already works: your AI tools, your alerts, your dashboards and your pull requests.

Next

AI & MCP

  • Plain-English explanations of findings, grounded in their evidence
  • MCP server with read-only tools for Claude, Cursor and your own agents
  • Chat with your database’s performance history
  • Local models through Ollama, so nothing leaves your network

Alerting

  • Alert rules per environment and severity
  • Slack, email, PagerDuty and signed webhooks
  • Weekly digest: regressions, validated fixes, time saved

Observability export

  • Prometheus metrics for your top queries
  • OpenTelemetry (OTLP) export
  • Ready-made Grafana dashboards

Stop regressions in CI

  • Pull request checks that compare plans and latency with main
  • Migration safety linter for locking and table-rewriting DDL
  • Deploy markers on every chart and finding
Later

Deeper diagnosis

  • Root-cause timelines that link related findings
  • Time-of-day baselines and anomaly detection
  • Index what-if with HypoPG before you create anything
  • Replication, WAL, vacuum progress and config advice
  • Capacity forecasts for disk, tables and connections

Cost & ownership

  • Database cost by role, application and team
  • Query ownership from sqlcommenter tags
  • Findings routed to the team that owns the query

Teams & platform

  • Authentication, SSO and roles
  • Fleet view across clusters and environments
  • CLI, Terraform provider and retention rollups
  • Helm chart and managed-cloud integrations

Plans, not promises. QueryPilot will never apply changes to your database on its own.Full roadmap →

FAQ

Questions before you point it at production.

More answers in the troubleshooting guide.

Will QueryPilot write to my database?

No. Every agent session is opened with default_transaction_read_only=on, so PostgreSQL itself rejects any write. Plan capture uses EXPLAIN (GENERIC_PLAN), which plans a query without running it, inside a read-only transaction that is rolled back. EXPLAIN ANALYZE is never run automatically.

Security model →
How much load does the agent add?

Very little, by design. It uses two connections at most, caps the rows of every collector query and sets a 5 second statement timeout. Collectors run every 5 to 60 seconds, and each run is scheduled from the end of the previous one, so a slow database gets longer gaps instead of a pile-up. The agent reports its own collection time on /metrics.

Installing the agent →
Which PostgreSQL versions are supported?

PostgreSQL 12 and newer. WAL metrics need 13+, and automatic plan capture needs 16+ because it relies on EXPLAIN (GENERIC_PLAN). On older versions you can still upload plans you captured yourself.

Does it work with Amazon RDS, Aurora, Cloud SQL or Azure?

Yes. QueryPilot only needs pg_stat_statements enabled and a role that can read the statistics views. On RDS and Aurora, add pg_stat_statements to the parameter group. On Cloud SQL, set the cloudsql.enable_pg_stat_statements flag. On Azure, set shared_preload_libraries. Run the agent anywhere that can reach both the database and the QueryPilot API.

PostgreSQL prerequisites →
Do I need a superuser?

No. A dedicated role with pg_read_all_stats and CONNECT covers everything. Plan capture also needs SELECT on the tables a query touches, because PostgreSQL requires it to plan the query. Without it, only those captures fail.

What data is stored, and does anything leave my network?

QueryPilot stores statistics, normalized query text and sanitized plans in its own PostgreSQL. Query parameters are never stored, and literal values are stripped from plans on your host before they are sent. You can turn query text off entirely. There is no hosted service and no phone-home telemetry.

Does it use AI to find problems?

No. Detection and recommendations come from deterministic rules you can inspect, and every finding shows the numbers behind it. Optional AI explanations are on the roadmap and will be off by default.

Is it free?

Yes. QueryPilot will be released as open source under the Apache-2.0 license, and it is self-hosted, so you run it on your own infrastructure at no cost. The repository is published at launch.

Is there authentication?

Not yet. It is on the roadmap. Until then, run QueryPilot on a trusted network, behind a VPN or behind an authenticating reverse proxy.

Production checklist →
What about MySQL or other databases?

QueryPilot is PostgreSQL only. Focusing on one database is what lets it read plans, locks and table health in depth.

Stop guessing why it’s slow.

The live demo runs the real interface on sample data. Follow a regression from the first finding to the verified fix.