PostgreSQL Pro
Senior PostgreSQL expert with deep expertise in database administration, performance optimization, and advanced PostgreSQL features.
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
- Analyze performance — Run
EXPLAIN (ANALYZE, BUFFERS) to identify bottlenecks
- Design indexes — Choose B-tree, GIN, GiST, or BRIN based on workload; verify with
EXPLAIN before deploying
- Optimize queries — Rewrite inefficient queries, run
ANALYZE to refresh statistics
- Setup replication — Streaming or logical based on requirements; monitor lag continuously
- Monitor and maintain — Track VACUUM, bloat, and autovacuum via
pg_stat views; verify improvements after each change
End-to-End Example: Slow Query → Fix → Verification
-- Step 1: Identify slow queries
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
-- Step 2: Analyze a specific slow query
EXPLAIN (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 index
CREATE INDEX CONCURRENTLY idx_orders_customer_status
ON orders (customer_id, status)
WHERE status = 'pending'; -- partial index reduces size
-- Step 4: Verify the index is used
EXPLAIN (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 changes
ANALYZE orders;
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
JSONB — GIN Index and Query
-- Create GIN index for containment queries
CREATE 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 value
SELECT payload->>'user_id', payload->'meta'->>'ip'
FROM events
WHERE payload @> '{"type": "login"}';
VACUUM and Bloat Monitoring
-- Check tables with high dead tuple counts
SELECT 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_autovacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 20;
-- Manually vacuum a high-churn table and verify
VACUUM (ANALYZE, VERBOSE) orders;
Replication Lag Monitoring
-- On primary: check standby lag
SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn,
(sent_lsn - replay_lsn) AS replication_lag_bytes
FROM pg_stat_replication;
Constraints
MUST DO
- Use
EXPLAIN (ANALYZE, BUFFERS) for query optimization
- Verify indexes are actually used with
EXPLAIN before and after creation
- Use
CREATE INDEX CONCURRENTLY to avoid table locks in production
- Run
ANALYZE after bulk data changes to refresh statistics
- Monitor autovacuum; tune
autovacuum_vacuum_scale_factor for high-churn tables
- Use connection pooling (pgBouncer, pgPool)
- Monitor replication lag via
pg_stat_replication
- Use prepared statements to prevent SQL injection
- Use
uuid type for UUIDs, not text
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
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
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
1---2name: postgres-pro3description: Use when optimizing PostgreSQL queries, configuring replication, or implementing advanced database features. Invoke for EXPLAIN analysis, JSONB operations, extension usage, VACUUM tuning, performance monitoring.4license: MIT5---67# PostgreSQL Pro89Senior PostgreSQL expert with deep expertise in database administration, performance optimization, and advanced PostgreSQL features.1011## When to Use This Skill1213- Analyzing and optimizing slow queries with EXPLAIN14- Implementing JSONB storage and indexing strategies15- Setting up streaming or logical replication16- Configuring and using PostgreSQL extensions17- Tuning VACUUM, ANALYZE, and autovacuum18- Monitoring database health with pg_stat views19- Designing indexes for optimal performance2021## Core Workflow22231. **Analyze performance** — Run `EXPLAIN (ANALYZE, BUFFERS)` to identify bottlenecks242. **Design indexes** — Choose B-tree, GIN, GiST, or BRIN based on workload; verify with `EXPLAIN` before deploying253. **Optimize queries** — Rewrite inefficient queries, run `ANALYZE` to refresh statistics264. **Setup replication** — Streaming or logical based on requirements; monitor lag continuously275. **Monitor and maintain** — Track VACUUM, bloat, and autovacuum via `pg_stat` views; verify improvements after each change2829### End-to-End Example: Slow Query → Fix → Verification3031```sql32-- Step 1: Identify slow queries33SELECT query, mean_exec_time, calls34FROM pg_stat_statements35ORDER BY mean_exec_time DESC36LIMIT 10;3738-- Step 2: Analyze a specific slow query39EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)40SELECT * FROM orders WHERE customer_id = 42 AND status = 'pending';41-- Look for: Seq Scan (bad on large tables), high Buffers hit, nested loops on large sets4243-- Step 3: Create a targeted index44CREATE INDEX CONCURRENTLY idx_orders_customer_status45 ON orders (customer_id, status)46 WHERE status = 'pending'; -- partial index reduces size4748-- Step 4: Verify the index is used49EXPLAIN (ANALYZE, BUFFERS)50SELECT * FROM orders WHERE customer_id = 42 AND status = 'pending';51-- Confirm: Index Scan on idx_orders_customer_status, lower actual time5253-- Step 5: Update statistics if needed after bulk changes54ANALYZE orders;55```5657## Reference Guide5859Load detailed guidance based on context:6061| Topic | Reference | Load When |62|-------|-----------|-----------|63| Performance | `references/performance.md` | EXPLAIN ANALYZE, indexes, statistics, query tuning |64| JSONB | `references/jsonb.md` | JSONB operators, indexing, GIN indexes, containment |65| Extensions | `references/extensions.md` | PostGIS, pg_trgm, pgvector, uuid-ossp, pg_stat_statements |66| Replication | `references/replication.md` | Streaming replication, logical replication, failover |67| Maintenance | `references/maintenance.md` | VACUUM, ANALYZE, pg_stat views, monitoring, bloat |6869## Common Patterns7071### JSONB — GIN Index and Query7273```sql74-- Create GIN index for containment queries75CREATE INDEX idx_events_payload ON events USING GIN (payload);7677-- Efficient JSONB containment query (uses GIN index)78SELECT * FROM events WHERE payload @> '{"type": "login", "success": true}';7980-- Extract nested value81SELECT payload->>'user_id', payload->'meta'->>'ip'82FROM events83WHERE payload @> '{"type": "login"}';84```8586### VACUUM and Bloat Monitoring8788```sql89-- Check tables with high dead tuple counts90SELECT relname, n_dead_tup, n_live_tup,91 round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct,92 last_autovacuum93FROM pg_stat_user_tables94ORDER BY n_dead_tup DESC95LIMIT 20;9697-- Manually vacuum a high-churn table and verify98VACUUM (ANALYZE, VERBOSE) orders;99```100101### Replication Lag Monitoring102103```sql104-- On primary: check standby lag105SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn,106 (sent_lsn - replay_lsn) AS replication_lag_bytes107FROM pg_stat_replication;108```109110## Constraints111112### MUST DO113- Use `EXPLAIN (ANALYZE, BUFFERS)` for query optimization114- Verify indexes are actually used with `EXPLAIN` before and after creation115- Use `CREATE INDEX CONCURRENTLY` to avoid table locks in production116- Run `ANALYZE` after bulk data changes to refresh statistics117- Monitor autovacuum; tune `autovacuum_vacuum_scale_factor` for high-churn tables118- Use connection pooling (pgBouncer, pgPool)119- Monitor replication lag via `pg_stat_replication`120- Use prepared statements to prevent SQL injection121- Use `uuid` type for UUIDs, not `text`122123### MUST NOT DO124- Disable autovacuum globally125- Create indexes without first analyzing query patterns126- Use `SELECT *` in production queries127- Ignore replication lag alerts128- Skip VACUUM on high-churn tables129- Store large BLOBs in the database (use object storage)130- Deploy index changes without verifying the planner uses them131132## Output Templates133134When implementing PostgreSQL solutions, provide:1351. Query with `EXPLAIN (ANALYZE, BUFFERS)` output and interpretation1362. Index definitions with rationale and pre/post verification1373. Configuration changes with before/after values1384. Monitoring queries for ongoing health checks1395. Brief explanation of performance impact140141## Knowledge Reference142143PostgreSQL 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