A query your agent wrote can pass every test and still read the whole table in production.

Your tests run on a few hundred rows, so they can’t show it. Query Doctor estimates the cost of the queries it sees against your production statistics, and comments on the pull request when one got more expensive, or when a new one needs an index or a rewrite.

Query Doctor — 1 failing and 4 successful checks
New query with index recommendation — 2 new queries ship a high-impact index recommendation
DashboardRepository.findFunnelCounts
dashboard.repository.ts · plans at 4,820, or 312 with this index
CREATE INDEX ON project_queries (project_id, last_seen_at);
New query — 6 new queries, none with a prior baseline
Cost regression — No query went up more than 10%
Untested data access — No changed data-access file without a test
Schema drift — No schema changes

Can’t I just ask Claude?

You can. It suggests an index or a rewrite from the SQL and whatever else it can read, and it sounds just as sure when it’s wrong.

With Query Doctor connected, it works from your production statistics instead. For any query it can see:

  • what the query costs, and whether that went up
  • what’s wrong with its plan or the schema
  • which index or rewrite makes it cheaper
  • how its cost is trending as your data grows, and what it would cost at 10x/100x

optimize_query(queryOrId: "SELECT COUNT(*) FROM project_queries WHERE …")

{
  "baseCost": 1215250.79,
  "optimizedCost": 41070.64,
  "costReductionPercentage": 96,
  "recommendations": [
    "project_queries(project_id, last_seen_at, hash)",
    "ci_runs_queries(hash, ci_run_id, optimization, created_at desc)"
  ],
  "findings": [
    {
      "title": "Correlated subquery runs once per row",
      "detail": "This Index Scan over `project_queries` runs a correlated subquery once per row, so about 100% of the cost is that repetition, not the scan. An index on `project_queries` can shrink the scan but not the per-row subqueries."
    }
  ]
}
What your agent gets when it asks Query Doctor about one of our queries while writing it.

What you get

Once your queries are tagged, every flagged query points to the line of code that sends it.

On the pull request:

queries that got more expensive than last time

Cost regression — 2 queries went up more than 10%, where either cost is at least 100
ProjectQueriesRepository.search · 1,245 on the baseline, 1,876 here (+51%)

new queries that need an index or a rewrite

New query with index recommendation — 2 new queries ship a high-impact index recommendation
DashboardRepository.findFunnelCounts · plans at 4,820, or 312 with this index

new queries that can return the wrong rows

Correctness finding — 1 new query can return wrong or unstable results

schema changes

Schema drift — The schema changed against the baseline
Added table public.statistics_snapshots

data-access code that changed without a test

Untested data access — 2 changed data-access files ship with no related test

In your agent, you can ask about any query and see what’s wrong with its plan and the rewritten version.

On our own repository, 41 of 285 queries came back with an index that would make them cheaper.

For 1 more, it found a rewrite of the SQL that costs 88% less.

We also timed two of our queries on a test database with our row counts, then with ten times as many rows. Our query search went from 2.5 seconds to 2 minutes 19 seconds. A count query went from 10 ms to 250 ms.

Questions

How is this different from running EXPLAIN, or my host’s query advisor?
EXPLAIN shows one plan, on whatever database you run it on. Your host’s advisor looks at production after a query has shipped. Query Doctor checks the queries a pull request runs before it merges, against your production statistics, tries the indexes and rewrites that would help, and remembers what each query cost last time.
What do I need to set it up?
For pull requests: GitHub Actions and a test suite that runs against a real Postgres. For your agent: an MCP client like Claude Code, and one line of config.
Which Postgres hosts does it work with?
Any Postgres you can connect to. The docs walk through Amazon RDS and Aurora, Supabase and Neon.
Which languages and ORMs does it work with?
Any that send SQL to Postgres, because it reads the queries your tests actually run. To point a finding at the line of code that sent it, your queries carry a small tag; there are guides for Drizzle, Prisma, TypeORM, MikroORM and EF Core.
Does it touch my production database?
It reads the statistics Postgres already keeps there. Every index and rewrite it tries runs on a separate Postgres, never on yours. If you ask it to, it can turn on pg_stat_statements for you.
What does Query Doctor see?
Your queries, your schema and their plans, which is how it can tell you when a query gets more expensive. For a query tagged with where it came from, also that file and line. If you connect a database, it also gets the statistics Postgres keeps, which include a sample of real values from each column.
Will it flood my pull requests with warnings?
You choose which checks can fail a pull request and how much more expensive a query has to get before it counts. When a query got slower because a table grew, the comment says so.
What about queries my tests don’t run?
It sees the queries your tests run, your agent asks about, or your database has recorded. Data-access code that changed without a test is flagged on the pull request.
What is “cost”?
Postgres’s own estimate of how much work a query takes: how many rows it has to read, and how it reads them. It’s the number EXPLAIN shows. It isn’t a time. A lower cost is usually a good sign that a query does less work, but not a guarantee, so your agent can try a change and compare. When a cost went up because a table grew rather than because of your change, the comment says so.
Can I self-host it?
Yes. There’s a reference Docker Compose setup in the docs, and your CI and agent point at your instance instead of ours.

One line to start

Add Query Doctor to your coding agent with one line of MCP config, and ask about a query you already suspect. When you want every pull request checked, ask the agent to set up CI. It writes the GitHub Actions workflow.

Interested in what we're up to?

No spam, pinky promise.