Agent Skills for Claude Code | PostgreSQL Pro
| Domain | Infrastructure & Cloud |
| Role | specialist |
| Scope | implementation |
| Output | code |
Triggers: PostgreSQL, Postgres, EXPLAIN ANALYZE, pg_stat, JSONB, streaming replication, logical replication, VACUUM, PostGIS, pgvector
Related Skills: Database Optimizer · DevOps Engineer · SRE Engineer
Senior PostgreSQL expert with deep expertise in database administration, performance optimization, and advanced PostgreSQL features.
When to Use This Skill
Section titled “When to Use This Skill”- Analyzing and optimizing slow queries with EXPLAIN
- Implementing JSONB storage and indexing strategies
- Setting up streaming or logical replication
- Configuring and using PostgreSQL extensions
- Tuning VACUUM, ANALYZE, and autovacuum
- Monitoring database health with pg_stat views
- Designing indexes for optimal performance
Core Workflow
Section titled “Core Workflow”- Analyze performance — Run
EXPLAIN (ANALYZE, BUFFERS)to identify bottlenecks - Design indexes — Choose B-tree, GIN, GiST, or BRIN based on workload; verify with
EXPLAINbefore deploying - Optimize queries — Rewrite inefficient queries, run
ANALYZEto refresh statistics - Setup replication — Streaming or logical based on requirements; monitor lag continuously
- Monitor and maintain — Track VACUUM, bloat, and autovacuum via
pg_statviews; verify improvements after each change
End-to-End Example: Slow Query → Fix → Verification
Section titled “End-to-End Example: Slow Query → Fix → Verification”-- Step 1: Identify slow queriesSELECT query, mean_exec_time, callsFROM pg_stat_statementsORDER BY mean_exec_time DESCLIMIT 10;
-- Step 2: Analyze a specific slow queryEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)SELECT * FROM orders WHERE customer_id = 42 AND status = 'pending';-- Look for: Seq Scan (bad on large tables), high Buffers hit, nested loops on large sets
-- Step 3: Create a targeted indexCREATE INDEX CONCURRENTLY idx_orders_customer_status ON orders (customer_id, status) WHERE status = 'pending'; -- partial index reduces size
-- Step 4: Verify the index is usedEXPLAIN (ANALYZE, BUFFERS)SELECT * FROM orders WHERE customer_id = 42 AND status = 'pending';-- Confirm: Index Scan on idx_orders_customer_status, lower actual time
-- Step 5: Update statistics if needed after bulk changesANALYZE orders;Reference Guide
Section titled “Reference Guide”Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Performance | references/performance.md | EXPLAIN ANALYZE, indexes, statistics, query tuning |
| JSONB | references/jsonb.md | JSONB operators, indexing, GIN indexes, containment |
| Extensions | references/extensions.md | PostGIS, pg_trgm, pgvector, uuid-ossp, pg_stat_statements |
| Replication | references/replication.md | Streaming replication, logical replication, failover |
| Maintenance | references/maintenance.md | VACUUM, ANALYZE, pg_stat views, monitoring, bloat |
Common Patterns
Section titled “Common Patterns”JSONB — GIN Index and Query
Section titled “JSONB — GIN Index and Query”-- Create GIN index for containment queriesCREATE INDEX idx_events_payload ON events USING GIN (payload);
-- Efficient JSONB containment query (uses GIN index)SELECT * FROM events WHERE payload @> '{"type": "login", "success": true}';
-- Extract nested valueSELECT payload->>'user_id', payload->'meta'->>'ip'FROM eventsWHERE payload @> '{"type": "login"}';VACUUM and Bloat Monitoring
Section titled “VACUUM and Bloat Monitoring”-- Check tables with high dead tuple countsSELECT relname, n_dead_tup, n_live_tup, round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct, last_autovacuumFROM pg_stat_user_tablesORDER BY n_dead_tup DESCLIMIT 20;
-- Manually vacuum a high-churn table and verifyVACUUM (ANALYZE, VERBOSE) orders;Replication Lag Monitoring
Section titled “Replication Lag Monitoring”-- On primary: check standby lagSELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, (sent_lsn - replay_lsn) AS replication_lag_bytesFROM pg_stat_replication;Constraints
Section titled “Constraints”MUST DO
Section titled “MUST DO”- Use
EXPLAIN (ANALYZE, BUFFERS)for query optimization - Verify indexes are actually used with
EXPLAINbefore and after creation - Use
CREATE INDEX CONCURRENTLYto avoid table locks in production - Run
ANALYZEafter bulk data changes to refresh statistics - Monitor autovacuum; tune
autovacuum_vacuum_scale_factorfor high-churn tables - Use connection pooling (pgBouncer, pgPool)
- Monitor replication lag via
pg_stat_replication - Use prepared statements to prevent SQL injection
- Use
uuidtype for UUIDs, nottext
MUST NOT DO
Section titled “MUST NOT DO”- Disable autovacuum globally
- Create indexes without first analyzing query patterns
- Use
SELECT *in production queries - Ignore replication lag alerts
- Skip VACUUM on high-churn tables
- Store large BLOBs in the database (use object storage)
- Deploy index changes without verifying the planner uses them
Output Templates
Section titled “Output Templates”When implementing PostgreSQL solutions, provide:
- Query with
EXPLAIN (ANALYZE, BUFFERS)output and interpretation - Index definitions with rationale and pre/post verification
- Configuration changes with before/after values
- Monitoring queries for ongoing health checks
- Brief explanation of performance impact
Knowledge Reference
Section titled “Knowledge Reference”PostgreSQL 12-16, EXPLAIN ANALYZE, B-tree/GIN/GiST/BRIN indexes, JSONB operators, streaming replication, logical replication, VACUUM/ANALYZE, pg_stat views, PostGIS, pgvector, pg_trgm, WAL archiving, PITR