Skip to main content

Analyze and compare PostgreSQL query plans

Project description

pgplan

GitHub Release npm PyPI Go Reference Go Report Card ci go version License

A command-line tool for analyzing and comparing PostgreSQL query execution plans. Get optimization insights and track performance regressions without leaving your terminal.

Features

  • Plan Analysis - Run 15+ intelligent rules against a query plan to surface performance issues with actionable fix suggestions
  • Plan Comparison - Semantically diff two plans side-by-side to understand what changed and whether it got better or worse
  • Flexible Input - Accept JSON EXPLAIN output, raw SQL files, stdin, or paste plans interactively
  • Connection Profiles - Save and manage named PostgreSQL connection strings for quick reuse
  • Multiple Output Formats - Human-readable colored terminal output or structured JSON for tooling integration

Installation

PyPI

pip install pgplan

npm

npm i -g pgplan

Go

go install github.com/jacobarthurs/pgplan@latest

Binary

Download the latest release for your platform from the releases page.

Quick Start

# Analyze a query plan from a JSON EXPLAIN output
pgplan analyze plan.json

# Analyze by running a SQL file against a database
pgplan analyze query.sql --db postgres://localhost:5432/mydb

# Compare two plans
pgplan compare before.json after.json

# Interactive mode - paste plans or queries directly into the terminal
pgplan analyze
pgplan compare

Commands

pgplan analyze [file]

Analyzes a single query plan and returns optimization findings sorted by severity.

Arguments:

Argument Description
file Path to a .json (EXPLAIN output) or .sql file. Use - for stdin. Omit for interactive mode.

Flags:

Flag Description
-d, --db PostgreSQL connection string (required for SQL input)
-p, --profile Named connection profile to use
-f, --format Output format: text (default) or json

Example:

pgplan analyze slow-query.sql --profile prod

pgplan compare [file1] [file2]

Compares two query plans and reports on cost, time, row estimate, and buffer differences across every node in the plan tree.

Arguments:

Argument Description
file1 The "before" plan. .json, .sql, - for stdin, or omit for interactive.
file2 The "after" plan. Same input options as file1.

Flags:

Flag Description
-d, --db PostgreSQL connection string (required for SQL input)
-p, --profile Named connection profile to use
-f, --format Output format: text (default) or json
-t, --threshold Percent change threshold for significance (default: 5)

Example:

pgplan compare before.json after.json --threshold 10

pgplan profile <subcommand>

Manages saved PostgreSQL connection profiles stored in ~/.config/pgplan/profiles.yaml.

Subcommand Description
list [--show] List saved profiles. Pass --show to display connection strings.
add <name> <conn_str> Add or update a named profile.
remove <name> Remove a profile.
default <name> Set a profile as the default.
clear-default Clear the default profile.

Example:

pgplan profile add prod postgres://user:pass@host:5432/mydb
pgplan profile default prod

# Now use it with analyze or compare
pgplan analyze query.sql --profile prod

Analysis Rules

The analyze command applies the following rules to identify performance issues. Each finding includes a severity level and an actionable suggestion.

Severity Rule Description
Critical Sort Spill to Disk Sort operation exceeded work_mem and spilled to disk
Warning Hash Spill to Disk Hash table exceeded work_mem
Warning Temp Block I/O Plan is reading/writing temporary blocks
Warning Seq Scan in Join Sequential scan used inside a join against a smaller set
Warning Seq Scan with Filter Standalone sequential scan filtering a large number of rows
Warning Index Scan Filter Inefficiency Index scan is fetching many rows then discarding most via filter
Warning Bitmap Heap Recheck Lossy bitmap scan rechecking conditions (bitmap exceeded work_mem)
Warning Nested Loop High Loops Nested loop executing 1,000+ iterations
Warning Correlated Subplan Subplan re-executing on every outer row
Warning Worker Launch Mismatch Fewer parallel workers launched than planned
Warning Parallel Overhead Parallel execution is slower than the serial estimate
Warning Large Join Filter Removal Join filter is discarding a large percentage of rows
Warning Excessive Materialization Materialize node looping many times
Info Low Selectivity Index Scan Index scan is returning most of the table
Info Wide Row Output Query is selecting more columns than necessary

Comparison Output

The compare command produces a structured diff of two plans including:

  • Summary - Overall cost, execution time, and buffer changes with directional indicators
  • Node Details - Per-node breakdown of metric changes (cost, rows, loops, buffers, filters, indexes)
  • Verdict - A final assessment such as "faster and cheaper" or "slower but cheaper"

Changes below the significance threshold (default 5%) are filtered out to reduce noise.

Output Formats

Text (default)

Colored terminal output with severity-coded findings and directional change indicators. Designed for quick human review.

JSON

Structured output suitable for piping into other tools, CI systems, or dashboards. Includes all metrics, findings, and comparison deltas.

pgplan analyze plan.json --format json | jq '.findings[] | select(.severity == "critical")'

Configuration

Connection Profiles

Profiles are stored in a YAML configuration file at the platform-appropriate config directory:

  • Linux/macOS: ~/.config/pgplan/profiles.yaml
  • Windows: %APPDATA%\pgplan\profiles.yaml
default: prod
profiles:
  - name: prod
    conn_str: postgres://user:pass@host:5432/production
  - name: dev
    conn_str: postgres://localhost:5432/development

Use --profile <name> with any command, or set a default to skip the flag entirely. The --db and --profile flags are mutually exclusive.

Contributing

Contributions are welcome! To get started:

  1. Fork the repository
  2. Create a feature branch (git checkout -b my-new-feature)
  3. Open a pull request

CI will automatically run tests and linting on your PR.

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pgplan-1.1.1-py3-none-win_arm64.whl (9.4 MB view details)

Uploaded Python 3Windows ARM64

pgplan-1.1.1-py3-none-win_amd64.whl (10.1 MB view details)

Uploaded Python 3Windows x86-64

pgplan-1.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (9.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

pgplan-1.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (9.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

pgplan-1.1.1-py3-none-macosx_11_0_arm64.whl (9.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

pgplan-1.1.1-py3-none-macosx_10_12_x86_64.whl (10.0 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file pgplan-1.1.1-py3-none-win_arm64.whl.

File metadata

  • Download URL: pgplan-1.1.1-py3-none-win_arm64.whl
  • Upload date:
  • Size: 9.4 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: Go-http-client/2.0

File hashes

Hashes for pgplan-1.1.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 53f6df6ebe3f4e804d527a2289003171fa878726e315d79194381a0e22f4fe0a
MD5 a3296aa803284c44802e220607c1a8b4
BLAKE2b-256 ad14ea0c0fa05bed553c54c6a8b008eb1d4a01cc83b355cd9ba63edab540e3d7

See more details on using hashes here.

File details

Details for the file pgplan-1.1.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: pgplan-1.1.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 10.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: Go-http-client/2.0

File hashes

Hashes for pgplan-1.1.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 9c29411b7a4ca2a1270a8b349e1ed4d9678969c20dea90d84ceca3d4c261e66a
MD5 5920e580ec38fd9ae86ce66b4819240f
BLAKE2b-256 19c69517abad68325ed417d7d41702251b608eb0c13bdece79fa4e3d8fd30d65

See more details on using hashes here.

File details

Details for the file pgplan-1.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pgplan-1.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ff4027ac5ebf1a5bcae14b7368bf825d43a365144e82f0d594e26a247a185ba3
MD5 8a5ac25a58c9176743b04105b27bf6be
BLAKE2b-256 090d2a81170b2c3a62fdd8f7bac02e06f10eb695be3741d2ea1f321cfae925ff

See more details on using hashes here.

File details

Details for the file pgplan-1.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pgplan-1.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4a51dd8023047b66663fd513b2a376e38395b8aca2c9179073c1c65017b68271
MD5 cab31a76684b493d5e3a8bf2f180e8aa
BLAKE2b-256 61d6b02ed718bc02221bfb17655d503628ec74c2138584906f0d9c6ac9d6db25

See more details on using hashes here.

File details

Details for the file pgplan-1.1.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pgplan-1.1.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 34903d36d19c46c2d69241f9105e53838b042e462f205bb3433d8302a24aca1b
MD5 94795f689b2dde50bb70061c1fc2f324
BLAKE2b-256 562488f3cb4c52059478e8e3d48c381edb4f0b5f0156fea28327450daef6dc12

See more details on using hashes here.

File details

Details for the file pgplan-1.1.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pgplan-1.1.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8b0f8013029aed69eb611868bbf2e6e6a2500befce289d12ef94d507548a1dbd
MD5 0ff5f0fc24eaa25880e4f911ec702c55
BLAKE2b-256 3285ff9da8112dc1ee20a761ebf5e6ac31a5cafc38e45619d366f772cb2ec1be

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page