Skip to main content

Function: createQueryPlanLogger()

createQueryPlanLogger(opts): QueryHooks

Defined in: src/observability/QueryPlanAnalyzer.ts:264

Creates a QueryHooks plugin that transparently runs EXPLAIN [ANALYZE] alongside each SELECT query and prints a rich, structured plan report with:

  • Estimated vs actual row counts (and accuracy percentage)
  • Total planner cost (coloured by magnitude)
  • Index names used at each plan node
  • Seq Scan detection with an actionable warning
  • Nested Loop warnings for large join results
  • Execution time breakdown (ANALYZE mode)

Dialect support:

  • PostgreSQL / Neon / CockroachDB / Supabase: full JSON plan tree with recursive node parsing
  • MySQL: text EXPLAIN output
  • SQLite / Turso / D1: EXPLAIN QUERY PLAN text output

Parameters​

ParameterTypeDescription
optsQueryPlanLoggerOptionsConfiguration options including the live adapter and analysis mode.

Returns​

QueryHooks

QueryHooks object ready to pass to options.withHooks(...).

Usecase​

Identify missing indexes, planner row-count mis-estimates, and expensive full-table scans directly in your server logs — in development or staging — without running separate database tooling.

Example​

// In onConfiguring() — always analyze SELECTs (EXPLAIN, no re-execution):
options.withHooks(
createQueryPlanLogger({ adapter })
);

// EXPLAIN ANALYZE only when query takes > 50ms:
options.withHooks(
createQueryPlanLogger({
adapter,
analyze: true,
thresholdMs: 50,
warnOnSeqScan: true,
onPlan: (plan) => {
if (plan.hasSeqScan) alerting.warn('seq_scan', plan.sql);
},
})
);