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.
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 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
new queries that need an index or a rewrite
new queries that can return the wrong rows
schema changes
data-access code that changed without a 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.
No spam, pinky promise.
DashboardRepository.findFunnelCounts