⚡ iCli — PostgreSQL Query & Index Profiler
iCli is a read-only Go CLI tool for slow query profiling, N+1 loop detection, execution plan analysis, and index auditing.
Note
🔒 Read-Only Guarantee: iCli only executes read-only SQL queries (SELECT metadata and EXPLAIN plan analysis). It never mutates, inserts, or deletes any data in your database.
Demo
Features
- N+1 Query Loop Detection: Identifies parameterized queries executing repeatedly in application loops (
WHERE col = $1), correlates parent/child queries, and recommends batched SQL (WHERE col = ANY(...)) or ORM prefetching. - Expensive Query Analysis: Identifies slow and resource-heavy queries using
pg_stat_statements. - Execution Plan Profiling: Runs
EXPLAIN (FORMAT JSON)and detects plan bottlenecks (e.g., sequential scans, disk sort spillage, inefficient joins). - Missing Foreign Key Index Detection: Finds foreign key constraints on child tables without a covering index, preventing severe sequential scan table locks on parent
UPDATEorDELETEoperations. - Unused Index Scanner: Identifies non-primary, non-unique indexes with zero recorded scans that degrade
INSERT/UPDATEperformance. - Table Bloat & Dead Tuple Auditor: Inspects
pg_stat_user_tablesviaicli bloatto identify tables with high dead tuple counts and ratio percentages that impair HOT update paths and degrade write throughput. - Sequence & Integer ID Overflow Auditor: Inspects sequence generators and primary key integer types via
icli sequenceto flag columns nearing max capacity before production outage risks occur. - Database Health Reports: Displays real-time database connection metrics, cache hit ratios, and server metadata via
icli report. - Modern Terminal UI: Formats findings into container cards, severity badges, rounded tables, and ready-to-run SQL remediation snippets powered by Lipgloss.
Requirements
- Go 1.25 or later.
- PostgreSQL with
pg_stat_statementsenabled.
Enable the extension at the server level, then restart PostgreSQL:
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
After restarting PostgreSQL, enable it in the target database:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
On a Homebrew PostgreSQL installation, restart with:
brew services restart postgresql@18
Quick Start
Install via go install
If you have Go installed, you can install icli directly:
go install github.com/abhiraj-ku/pg_adv/cmd/icli@latest
Run Locally / From Source
Clone the repository and run the CLI with a PostgreSQL connection string.
DSN resolution order:
-d/--dsnPGDSNenvironment variable
Examples:
git clone https://github.com/abhiraj-ku/iCli.git cd iCli export PGDSN="postgres://postgres@localhost:5432/postgres?sslmode=disable" # Display interactive CLI commands menu & guide icli # Analyze top slow queries & execution plans icli analyze -n 5 # Detect N+1 query patterns & loop bottlenecks icli n1query -m 50 # Scan for unused indexes and missing foreign key indexes icli index icli index unused icli index missing-fk # Generate an instant database health summary report icli report # Audit sequence capacity and integer ID overflow risks (filter threshold >= 50%) icli sequence -t 50 # Detect table bloat and dead tuples slowing down write operations icli bloat # Filter table bloat with custom thresholds (min 10% bloat ratio, min 500 dead tuples, limit top 10) icli bloat -t 10 -m 500 -l 10 # Help command icli --help
Or pass the DSN explicitly:
icli analyze -d="postgres://postgres@localhost:5432/postgres?sslmode=disable"The long-form flag is also supported:
icli analyze --dsn="postgres://postgres@localhost:5432/postgres?sslmode=disable"Build a binary with:
go build -o icli ./cmd/icli export PGDSN="postgres://postgres@localhost:5432/postgres?sslmode=disable" ./icli analyze
Developer Setup
Prerequisites
- Go 1.25 or later
- PostgreSQL instance running locally or remotely
pg_stat_statementsenabled in the target database- A valid DSN available through either
-d/--dsnorPGDSN
Local database setup
Create a local PostgreSQL database and enable the extension:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
Then export the connection string for local development:
export PGDSN="postgres://postgres@localhost:5432/postgres?sslmode=disable"
Repo layout
cmd/icli— CLI entrypoint and subcommand routing (analyze,index,n1query,report,sequence,update)internals/analyzer— execution-plan issue rules, N+1 loop detection heuristics, and sequence overflow analysisinternals/db— PostgreSQL queries (pg_stat_statements, unused indexes, unindexed foreign keys, sequence capacity, N+1 candidate query stats)internals/health— database health stats collection (cache hit ratio, active connections)internals/report— modern Lipgloss terminal TUI rendering
Common dev commands
go test ./...
go run ./cmd/icli
go run ./cmd/icli sequence -t 50
go run ./cmd/icli reportTroubleshooting
- If you see
connection refused, confirm PostgreSQL is running and the host/port are correct. - If the slow query report is empty, ensure
pg_stat_statementsis enabled and queries have been executed. - If the DSN is missing, pass
-d/--dsnor exportPGDSN. - If formatting looks odd in a narrow terminal, run it in a wider terminal or resize the window.
Releases
Prebuilt releases are available for these platforms on the GitHub Releases page:
| Platform | Architecture | Archive name pattern |
|---|---|---|
| Linux | x86_64 | icli_Linux_x86_64.tar.gz |
| macOS (Apple Silicon, M-series) | ARM 64-bit | icli_Darwin_arm64.tar.gz |
Download the archive for your platform from the Releases page, extract it, and run icli:
tar -xzf icli_Darwin_arm64.tar.gz
./icli -dsn="postgres://user:password@localhost:5432/database?sslmode=disable"Windows and Intel macOS binaries are not included in releases.
How It Works
- Reads the PostgreSQL server version to select the correct execution-time column (
total_timevstotal_exec_time). - Queries
pg_stat_statementsand excludesiCli's internal telemetry queries. - Analyzes high-frequency parameterized queries (
WHERE col = $1), detecting N+1 application loop patterns and correlating parent/child queries. - Sanitizes parameter placeholders before requesting an
EXPLAIN (FORMAT JSON)plan. - Walks execution plans and reports bottlenecks like sequential scans, disk sort spillage, and inefficient nested loops.
- Queries
pg_stat_user_indexesandpg_indexto find non-primary, non-unique indexes with 0 recorded scans. - Inspects
pg_constraint,pg_attribute, andpg_indexto detect unindexed foreign keys on child tables. - Queries
pg_sequencesand system dependencies to calculate sequence percentage utilization (last_value / max_value) and map sequences totable.columnpairs, generating zero-downtimeBIGINTmigration DDL commands for columns nearing capacity limits. - Queries
pg_stat_user_tablesto analyze dead tuple accumulation (n_dead_tup), bloat ratio percentage (n_dead_tup / (n_live_tup + n_dead_tup)), and autovacuum execution history. Filters results using-t/--threshold,-m/--min-dead, and-l/--limit, outputting actionableVACUUM ANALYZEand autovacuum tuning DDL recommendations.
