PostgreSQL EXPLAIN Viewer

A tool that shows PostgreSQL EXPLAIN (ANALYZE, FORMAT JSON) output as a tree of plan nodes. You can check node types, estimated and actual rows, loops, and actual time, with self time that accounts for loops and highlighted row misestimates. No database connection is made — everything runs in your browser.

Your plan is never sent to a server. Everything is analyzed in your browser, with no database connection or SQL execution.

Paste the output of EXPLAIN (ANALYZE, FORMAT JSON) to see the plan as a tree.

How to use

  1. Run EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT ...; in a test environment and copy the output.
  2. Paste the output or load a file. Headers and trailing + from psql's table output are removed automatically.
  3. Use the summary to find nodes with the most self time and the largest row misestimates.
  4. Expand and collapse nodes in the tree to check conditions (Filter, Index Cond, and so on) and rows removed.

About this tool

The cause of a slow query is often visible in where the plan spends time and where the planner's row estimates are far off. This tool turns hard-to-read JSON plans into a tree and highlights those spots.

PostgreSQL reports actual time and rows per loop, and a node's time includes its children. This tool multiplies by loops and subtracts the children's time to estimate each node's self time, so you aren't misled by simply adding up times. Parallel nodes under Gather are divided by the number of processes.

For plans without ANALYZE, actual values are shown as "—" rather than 0. An estimate of 0 rows is compared as at least 1 row, so there are no calculation errors. No database connection or SQL execution happens — only the plan you paste is analyzed.

As a minimal example, paste [{"Plan":{"Node Type":"Seq Scan","Relation Name":"users","Plan Rows":10}}]. The tree shows a Seq Scan on users. Because no measured execution data is provided, actual time is treated as unavailable rather than assumed to be zero.

A gap between estimated and actual rows is a clue, not proof that a particular index is needed. Read conditions and loop counts alongside it. The viewer only parses the JSON you provide and does not query PostgreSQL from the browser.

Frequently asked questions

Does it support text-format EXPLAIN?

This version supports FORMAT JSON output only. Capture the plan with EXPLAIN (ANALYZE, FORMAT JSON).

Is the self time exact?

It's an estimate. CTEs, InitPlans, and parallel execution account for time differently, so it may be off. Negative values are shown as 0.

Is it safe to paste plans from production?

Plans are analyzed only in your browser and never sent to a server. Note that EXPLAIN ANALYZE actually runs the query, so capture plans in a test environment when possible.