pg-dash
The AI-native PostgreSQL health checker. Three commands cover ~90% of day-to-day use β check-migration, check, bloat. Plus 26 MCP tools for deeper analysis (including pgvector health), Streamable HTTP transport for shared team servers, and a web dashboard for continuous monitoring.
π Read the full writeup on Dev.to
Daily drivers
Three commands cover the 80/20 case. Wire them into your workflow and you'll rarely need the rest:
| Command | When to run | |---|---| | pg-dash check-migration <file> <conn> | Before every migration deploy (CI or pre-commit) | | pg-dash check <conn> (alias health) | Pre-deploy checklist | | pg-dash bloat <conn> | Scheduled cleanup (unused indexes, dead tuples) |
For anything deeper β EXPLAIN analysis, schema diff, pgvector health, activity monitoring, query stats export β see the full command list below or call the 26 MCP tools from your AI agent.
Not another monitoring dashboard β pg-dash is built to fit into your AI coding workflow:
Developer writes a migration β pg-dash check-migration (pre-flight) β
CI runs pg-dash check β Finds missing indexes β
MCP tool suggests fix β PR comment
# One-shot health check
npx @indiekitai/pg-dash check postgres://user:pass@host/db
# Check migration safety before running it
npx @indiekitai/pg-dash check-migration ./migrations/015_add_index.sql
# EXPLAIN ANALYZE a slow query in the terminal
npx @indiekitai/pg-dash explain "SELECT * FROM orders WHERE user_id = 1" postgres://...
# Real-time lock + long-query monitor (Ctrl+C to exit)
npx @indiekitai/pg-dash watch-locks postgres://...
# Analyze slow queries from pg_stat_statements
npx @indiekitai/pg-dash slow-queries postgres://... --limit 20 --min-calls 5
# Analyze table/index bloat
npx @indiekitai/pg-dash bloat postgres://...
# Compare two environments (local vs staging)
npx @indiekitai/pg-dash diff-env --source postgres://localhost/db --target postgres://staging/db
# AI assistant (Claude/Cursor) via MCP
pg-dash-mcp postgres://user:pass@host/db
# CI pipeline with diff
npx @indiekitai/pg-dash check $DATABASE_URL --ci --diff --format md
Philosophy
Developer tools are use-and-go. You don't stare at a PostgreSQL dashboard all day. You run a check, fix the issues, and move on. pg-dash embraces this:
- Health check β Find problems, get actionable SQL fixes, done
- MCP tools β Let your AI assistant query and fix your database directly (unique β pganalyze/pgwatch don't have this)
- CI integration β Catch issues automatically on every migration, not when production is on fire
- Smart diff β See what changed since last run, track your progress
The Dashboard is there when you need it. But the real power is in the CLI, MCP, and CI.
Why pg-dash?
| Tool | Price | Setup | AI-native | CI-ready | |------|-------|-------|-----------|----------| | pganalyze | $149+/mo | SaaS signup | β | β | | Grafana+Prometheus | Free | 3 services | β | β | | pgAdmin | Free | Complex UI | β | β | | pg-dash | Free | One command | 25 MCP tools | --ci --diff |
Security: SQL Safety by Design
Note: The official Anthropic PostgreSQL MCP server has a known SQL injection vulnerability that bypasses its read-only transaction wrapper. pg-dash takes a different approach.
pg-dash enforces SQL safety at multiple layers:
- Read-only by default β All MCP query tools run inside
SET TRANSACTION READ ONLYwith parameterized queries. No raw SQL passthrough. - Strict write allowlist β The
pg_dash_fixtool only executes pre-approved operations:VACUUM,ANALYZE,REINDEX,CREATE INDEX CONCURRENTLY,DROP INDEX CONCURRENTLY. Everything else is rejected. - No arbitrary SQL execution β Unlike servers that expose a generic
querytool, pg-dash exposes purpose-built tools (pg_dash_health,pg_dash_explain,pg_dash_bloat, etc.) that construct their own SQL internally. - Connection string isolation β Each MCP session is bound to the connection string provided at startup. No tool can connect to a different database.
Features
π Real-time Monitoring
- Live connection count, TPS, cache hit ratio, DB size
- Time-series charts with range selector (5m β 7d)
- WebSocket-powered auto-refresh
- Active query list with cancel support
- π UI available in English and δΈζ (simplified Chinese); per-browser preference saved to localStorage
π₯ Health Advisor
- 46+ automated checks across performance, maintenance, schema, and security
- A-F health grade with category breakdown
- One-click fixes β not just "here's what's wrong" but "click to fix it"
- SQL allowlist (only safe operations: VACUUM, ANALYZE, REINDEX, etc.)
π Schema Browser
- Browse all tables, columns, indexes, constraints, foreign keys
- Sample data preview
- Index usage stats
- Extension and enum type listing
π Schema Change Tracking
- Automatic schema snapshots (every 6 hours)
- Detects: tables added/removed, columns changed, indexes modified
- Timeline view with diff comparison
- The sticky feature β gets more valuable over time
π Alerts
- 7 default alert rules (connection utilization, cache ratio, long queries, etc.)
- Custom rules via API
- Cooldown support (no alert spam)
- Webhook notifications
- Alert history
π EXPLAIN Plan Visualization
- Click any query in the Queries tab to see its execution plan
- Tree view of the EXPLAIN output for easy analysis
π Query Time-Series Trends
- Trends tab with historical pg_stat_statements snapshots
- Track query performance over time
πΎ Disk Space Monitoring
- Disk tab with per-table size breakdown
- Growth prediction using linear regression
- "Days until disk full" estimate
π£ Slack & Discord Notifications
- Webhook notifications for alerts
- Auto-detects Slack vs Discord webhook URLs
- Configure via
--slack-webhookor--discord-webhook
π¬ EXPLAIN ANALYZE CLI
pg-dash explain "SELECT * FROM orders WHERE user_id = 1" postgres://...
Query: SELECT * FROM orders WHERE user_id = 1
Limit cost=3.01..3.04 actual=0.060ms rows=10/10
ββ Sort cost=3.01..3.09 actual=0.057ms rows=10/32
ββ Seq Scan on users cost=0.00..2.32 actual=0.023ms rows=32/32
βββ Summary ββββββββββββββββββββββββββββββββββββ
Execution time: 0.087ms
Planning time: 0.756ms
Seq Scans: users
βββ Recommendations ββββββββββββββββββββββββββββ
βΉ Sort on [created_at DESC]. An index might eliminate this.
- Color-coded node types: π΄ Seq Scan, π’ Index Scan, π‘ Hash Join, π£ Sort
- Shows actual vs estimated rows β catches bad planner estimates
- Flags Seq Scans > 1000 rows, Sort nodes, Hash Join memory spills
--no-analyzefor dry EXPLAIN (no actual execution)--jsonfor scripting
π watch-locks
pg-dash watch-locks postgres://...
Real-time lock wait monitor β refreshes every 3 seconds. Shows:
- Blocked queries with PID, wait time, and the blocking query
- Long-running queries (configurable threshold via
--long-query-threshold) - Table and lock type for each wait
π query-stats (PG 18+)
# Export query statistics from production
pg-dash query-stats export postgres://prod-server/db --file prod-stats.json
# Import to development environment
pg-dash query-stats import prod-stats.json postgres://localhost/db
Export/import PostgreSQL query statistics (requires PG 18+). Enables "production query plans without production data" workflow:
- Export stats from production:
pg-dash query-stats export prod - Import to dev:
pg-dash query-stats import prod-stats.json dev - Run
EXPLAINlocally β now uses production statistics for accurate query plans
The exported JSON is typically <1MB regardless of database size.
π‘οΈ Migration Safety Check
- Analyze a migration SQL file for risks before running it
- Detects:
CREATE INDEXwithoutCONCURRENTLY(lock risk),ADD COLUMN NOT NULLwithoutDEFAULT,ALTER COLUMN TYPE(full table rewrite),DROP COLUMN(app breakage risk),ADD CONSTRAINTwithoutNOT VALID(full table scan),CREATE INDEX CONCURRENTLYinside a transaction (runtime failure),DROP TABLE,TRUNCATE,DELETE/UPDATEwithoutWHERE - Dynamic checks: connects to DB to verify referenced tables exist, estimates lock time based on actual row counts
- CI-ready:
--ciflag emits::error::/::warning::GitHub Actions annotations
π§ Query Intelligence
pg_dash_analyze_queryβ runsEXPLAIN ANALYZE, detects Seq Scans on large tables, auto-generatesCREATE INDEX CONCURRENTLYsuggestions with benefit ratingspg_dash_query_regressionsβ finds queries that got >50% slower vs historical baseline (requirespg_stat_statements)- EXPLAIN Modal in dashboard shows index suggestions inline
π Multi-Env Diff
- Compare schema and health between two PostgreSQL environments (local vs staging, staging vs prod)
- Detects: missing/extra tables, missing/extra columns, column type mismatches, missing/extra indexes, foreign key and CHECK constraints, enum type differences
--healthflag adds health score comparison and unique issues per environmentpg_dash_compare_envMCP tool: ask your AI "what's different between local and staging?"
π§ Production Readiness Audit
- Unused indexes β Find indexes with 0 scans since last stats reset; suggests safe
DROP INDEX CONCURRENTLYSQL - Table bloat β Dead tuple ratio per table (β₯10%); surfaces both
last_autovacuumandlast_vacuumtimestamps - Autovacuum health β Classifies each table as
ok/stale/overdue/never; shows autovacuum settings with units - Lock monitoring β Active lock-wait chains (who is blocking whom) + long-running queries >5s
- Config recommendations β Audits
shared_buffers,work_mem,checkpoint_completion_target,random_page_cost,idle_in_transaction_session_timeout, and 5 more settings with severity-tagged recommendations
𧬠pgvector Health Check
pg-dash pgvector postgres://...
Checks pgvector installation and index health:
- Installed version and upgrade recommendations
- Vector columns with dimension analysis (flags >2000d for performance)
- Index types (IVFFlat vs HNSW) with parameter tuning suggestions
- IVFFlat
listsvs row count validation (should be ~βrows) - HNSW
ef_constructionvsmratio check - Missing vector indexes on large tables
- Index size vs table size ratio
MCP tool: pg_dash_pgvector
π€ MCP Server
- 26 tools for AI agent integration
- Stdio (default):
pg-dash-mcp postgres://...β local use with Claude, Cursor, etc. - Streamable HTTP:
pg-dash-mcp postgres://... --httpβ shared team server, compatible with MCP 2026-07-28 stateless spec
# Remote mode β shared team server on port 8768
pg-dash-mcp postgres://... --http
# Custom port
MCP_PORT=9000 pg-dash-mcp postgres://... --http
MCP client config for remote mode: ``json { "mcpServers": { "pg-dash": { "type": "streamable-http", "url": "http://your-server:8768/mcp" } } } ``
π₯οΈ CLI
# Start dashboard
pg-dash postgres://user:pass@host/db
# Health check (great for CI/CD)
pg-dash check postgres://user:pass@host/db
pg-dash check postgres://... --format json --threshold 70
# Migration safety check
pg-dash check-migration ./migrations/015_add_index.sql
pg-dash check-migration ./migrations/015_add_index.sql postgres://... --ci
# Multi-env schema diff
pg-dash diff-env --source postgres://localhost/db --target postgres://staging/db
pg-dash diff-env --source postgres://... --target postgres://... --health --format md
# Schema changes
pg-dash schema-diff postgres://user:pass@host/db
Quick Start
# Using npx (no install needed)
npx @indiekitai/pg-dash postgres://user:pass@localhost/mydb
# Or install globally
npm install -g @indiekitai/pg-dash
pg-dash postgres://user:pass@localhost/mydb
# With individual options
pg-dash --host localhost --user postgres --db mydb --port 3480
Opens your browser at http://localhost:3480 with the full dashboard.
Documentation
- Real-world example β pg-dash running against a production database
- Migration safety guide β catching lock risks before they hit production
- MCP setup guide β connecting to Claude Desktop and Cursor
- CI integration guide β automated checks in GitHub Actions
CLI Options
pg-dash <connection-string> Start dashboard
pg-dash check <connection-string> Run health check and exit
pg-dash check-migration <file> [conn] Analyze migration SQL for risks
pg-dash diff-env --source <url> --target <url> Compare two environments
pg-dash schema-diff <connection-string> Show schema changes
Options:
-p, --port <port> Dashboard port (default: 3480)
--no-open Don't auto-open browser
--json Dump health check as JSON and exit
--host <host> PostgreSQL host
-u, --user <user> PostgreSQL user
--password <pass> PostgreSQL password
-d, --db <database> PostgreSQL database
--pg-port <port> PostgreSQL port (default: 5432)
--data-dir <dir> Data directory (default: ~/.pg-dash)
-i, --interval <sec> Collection interval (default: 30)
--threshold <score> Score threshold for check command (default: 70)
-f, --format <fmt> Output format: text|json|md (default: text)
--query-stats-interval <min> Query stats snapshot interval in minutes (default: 5)
--slack-webhook <url> Slack webhook URL for alert notifications
--discord-webhook <url> Discord webhook URL for alert notifications
--ci Output GitHub Actions annotations (check, check-migration, diff-env)
--diff Compare with last snapshot (check command)
--ai-suggest Use AI to generate fix suggestions (requires LLM config)
--ai-explain Use AI to explain schema diff business impact (requires LLM config)
--snapshot-path <path> Path to snapshot file for --diff
--health Include health comparison (diff-env)
-v, --version Show version
MCP Server
For AI agent integration:
# Start MCP server
pg-dash-mcp postgres://user:pass@host/db
# Or with env var (PG_DASH_CONNECTION_STRING or DATABASE_URL)
PG_DASH_CONNECTION_STRING=postgres://... pg-dash-mcp
Available Tools (26)
| Tool | Description | |------|-------------| | pg_dash_overview | Database overview (version, uptime, size, connections) | | pg_dash_health | Health advisor report with score, grade, and issues | | pg_dash_tables | List all tables with sizes and row counts | | pg_dash_table_detail | Detailed info about a specific table | | pg_dash_activity | Current database activity (active queries, connections) | | pg_dash_schema_changes | Recent schema changes | | pg_dash_fix | Execute a safe fix (VACUUM, ANALYZE, REINDEX, etc.) | | pg_dash_alerts | Alert history | | pg_dash_explain | Run EXPLAIN ANALYZE on a SELECT query (read-only) | | pg_dash_batch_fix | Get batch fix SQL for issues, optionally filtered by category | | pg_dash_slow_queries | Top slow queries from pg_stat_statements | | pg_dash_table_sizes | Table sizes with data/index breakdown (top 30) | | pg_dash_export | Export full health report (JSON or Markdown) | | pg_dash_diff | Compare current health with last saved snapshot | | pg_dash_check_migration | Analyze migration SQL for lock risks, missing tables, destructive ops | | pg_dash_analyze_query | Deep EXPLAIN analysis with automatic index suggestions | | pg_dash_query_regressions | Detect queries that degraded >50% vs historical baseline | | pg_dash_compare_env | Compare schema and health between two database environments | | pg_dash_unused_indexes | Find unused indexes that waste space and slow down writes | | pg_dash_bloat | Detect table bloat (dead tuples) that slow down queries | | pg_dash_autovacuum | Check autovacuum health β which tables are stale or never vacuumed | | pg_dash_locks | Show active lock waits and long-running blocking queries | | pg_dash_config_check | Audit PostgreSQL configuration and get tuning recommendations | | pg_dash_pgvector | pgvector health β installed version, vector columns, index types (IVFFlat/HNSW), dimension analysis, tuning | | fetch_db_context | Comprehensive DB context for AI agents: all table structures, columns, types, PKs/FKs, indexes, business intent inference, and health summary (single call for full context) | | pg_dash_query_natural | Query database using natural language β LLM converts your question to SQL and returns results | | ci_health_summary | CI-friendly health summary with AI-powered prioritization |
MCP Setup
Connect pg-dash to Claude Desktop or Cursor for AI-assisted database management.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"pg-dash": {
"command": "npx",
"args": ["-y", "-p", "@indiekitai/pg-dash", "pg-dash-mcp", "postgresql://user:pass@host/db"]
}
}
}
Claude Code
Add to ~/.claude/mcp.json (global) or .mcp.json (project-level):
{
"mcpServers": {
"pg-dash": {
"command": "npx",
"args": ["-y", "-p", "@indiekitai/pg-dash", "pg-dash-mcp", "postgresql://user:pass@host/db"]
}
}
}
Cursor
Add to .cursor/mcp.json in your project:
{
"mcpServers": {
"pg-dash": {
"command": "npx",
"args": ["-y", "-p", "@indiekitai/pg-dash", "pg-dash-mcp", "postgresql://user:pass@host/db"]
}
}
}
Example Conversations
Once connected, you can ask your AI assistant:
Diagnosis:
- "What's wrong with my database right now?"
- "Why is my
userstable slow? Check for missing indexes." - "Show me the top 5 slowest queries this week."
Optimization:
- "Generate SQL to fix all missing FK indexes in one go."
- "EXPLAIN this query for me: SELECT * FROM orders WHERE user_id = 123"
- "Which tables are taking up the most space?"
Pre-migration check:
- "Run a health check and tell me if it's safe to deploy."
- "What changed in the schema since last week?"
- "Check if there are any idle connections blocking my migration."
CI Integration
GitHub Actions
Add --ci and --diff flags to integrate with CI pipelines:
# GitHub Actions annotations (::error::, ::warning::)
pg-dash check postgres://... --ci
# Markdown report for PR comments
pg-dash check postgres://... --ci --format md
# Compare with previous run
pg-dash check postgres://... --diff
# All together
pg-dash check postgres://... --ci --diff --format md
Sample workflow (.github/workflows/pg-check.yml):
name: Database Health Check
on:
push:
paths: ['migrations/**', 'prisma/**', 'drizzle/**', 'supabase/migrations/**']
pull_request:
paths: ['migrations/**', 'prisma/**', 'drizzle/**', 'supabase/migrations/**']
schedule:
- cron: '0 8 * * 1' # Weekly Monday 8am UTC
jobs:
db-health:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Cache snapshot across ephemeral runners for --diff to work
- name: Restore health snapshot
uses: actions/cache@v4
with:
path: .pg-dash-cache
key: pg-dash-snapshot-${{ github.ref }}
restore-keys: pg-dash-snapshot-
- name: Run pg-dash health check
id: pg-check
run: |
mkdir -p .pg-dash-cache
npx @indiekitai/pg-dash check ${{ secrets.DATABASE_URL }} \
--ci --diff --snapshot-path ./.pg-dash-cache/last-check.json \
--format md > pg-dash-report.md
echo "exit_code=$?" >> $GITHUB_OUTPUT
continue-on-error: true
- name: Save health snapshot
uses: actions/cache/save@v4
if: always()
with:
path: .pg-dash-cache
key: pg-dash-snapshot-${{ github.ref }}-${{ github.run_id }}
- name: Fail if unhealthy
if: steps.pg-check.outputs.exit_code != '0'
run: exit 1
See examples/github-actions-pg-check.yml for a full workflow with PR comments.
Health Checks
pg-dash runs 46+ automated checks:
Performance
- Missing indexes (high sequential scans on large tables)
- Bloated indexes (index size vs table size)
- Table bloat (dead tuple ratio)
- Cache efficiency per table
- Slow queries (from pg_stat_statements)
Maintenance
- VACUUM overdue
- ANALYZE overdue
- Transaction ID wraparound risk
- Idle connection detection
- Idle in transaction detection
Schema
- Missing primary keys
- Unused indexes (0 scans, >1MB)
- Duplicate indexes
- Missing foreign key indexes
Security
- Remote superuser connections
- SSL disabled
- Trust authentication (no password)
CI/CD Integration
# Fail pipeline if health score < 70
pg-dash check postgres://... --threshold 70 --format json
# Example GitHub Actions
- name: Database Health Check
run: npx @indiekitai/pg-dash check ${{ secrets.DATABASE_URL }} --threshold 70
Data Storage
pg-dash stores metrics locally in ~/.pg-dash/:
metrics.dbβ Time-series metrics (7-day retention)schema.dbβ Schema snapshots and change historyalerts.dbβ Alert rules and history
All SQLite. No external dependencies. Delete the folder to reset.
Tech Stack
- Backend: Hono + Node.js
- Frontend: React + Tailwind CSS (bundled)
- Storage: SQLite (better-sqlite3)
- Charts: Recharts
- Zero external services required
Requirements
- Node.js 18+
- PostgreSQL 12+ (some features require 15+)
License
MIT
---
Built by IndieKit β open-source developer tools with MCP support.
History
pg-dash has consolidated functionality from several earlier packages, all now archived:
- pg-inspect β schema introspection (use
pg-dash schema-diffor inspection routes) - pg-top β realtime activity monitor (use
pg-dash watch-locks) - pg-explain β EXPLAIN ANALYZE visualization (use
pg-dash explain) - pg-horizon β MVCC horizon monitoring (covered by pg-dash's
Transaction ID Agecheck)
If you've installed any of these as standalone npm packages, switch to pg-dash β same functionality, one install, one upgrade path.






