Skip to content

Cost Breakdown

Standard PostgreSQL EXPLAIN gives each node a single Total Cost number, a unitless estimate of how expensive that step is. The cost breakdown, marked with an asterisk (*), splits that number into its component parts so you can see why a node is expensive, not just that it is.

Stock PostgreSQL does not report it. It comes from the patched planner Query Doctor costs your queries on.

Each cost breakdown is a list of reasons with their cost contribution:

Field Description
Reason What this portion of the cost represents
Cost The numeric cost attributed to this reason

The reasons sum to the node’s Total Cost. In the tree view, Query Doctor renders these as a color-coded bar where each segment represents a different reason. Hovering over a segment shows the reason, its cost, and its percentage of the total.

A node’s Total Cost is one number; it doesn’t separate the work behind it. Two nodes can have the same cost for completely different reasons — one might be dominated by I/O from reading heap pages, while the other is bottlenecked by CPU-intensive filtering. The breakdown reveals which component is the dominant contributor, which helps you choose the right optimization:

  • High I/O cost — the node is reading many pages from disk or shared buffers. A more selective index or covering index (Index Only Scan) could reduce the pages touched.
  • High CPU/filter cost — the node reads rows efficiently but discards many through filtering. A more targeted index that pushes the filter into the index condition could eliminate the wasted work.
  • High startup cost — the node spends significant effort before returning its first row. This matters most for queries with LIMIT that only need early results.

Cost breakdowns can appear on any plan node, but are most actionable on scan nodes (Seq Scan, Index Scan, Bitmap Heap Scan, etc.) where you have direct control over access paths via indexes.

Cost breakdowns also appear within alternative plans, letting you compare not just the total cost of each rejected path but the shape of its cost — useful for understanding what makes an alternative more expensive than the chosen plan.

The planner reports it itself. Each component carries the cost model parameter it came from (seq_page_cost, random_page_cost, cpu_tuple_cost, and the rest) and the row counts that parameter was charged against, because the planner is the only thing that knows how it reached the number.

The planner runs on the Query Doctor instance: a PostgreSQL container matched to your database’s major version, holding your schema and your table statistics and none of your rows. The Collector sends them.

All augmented fields are marked with an asterisk (*) in the UI and include a tooltip noting they are not part of standard PostgreSQL EXPLAIN output.