You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Missing Statistics** - Tables never analyzed, leaving the query planner without statistics
78
-
-**Duplicate Indexes** - Multiple indexes with identical or overlapping column sets
78
+
-**Duplicate Indexes** - Indexes with the same structure, including predicates and expressions
79
79
-**Inactive Replication Slots** - Identifies replication slots that are inactive and can be removed if no longer needed
80
80
-**Tables Larger Than 100GB** - Identifies tables that are larger than 100GB
81
81
-**Tables With More Than 200 Columns** - List tables with more than 200 columns. You should probably look into those...
@@ -121,8 +121,8 @@ That's it! No configuration needed. Deploy as a user with the highest possible p
121
121
-**PostgreSQL Version** - Version information and configuration details
122
122
-**Installed Extensions** - Lists installed extensions on the Server
123
123
-**Server Uptime** - Server uptime since last restart
124
-
-**Log Directory** - Location of Log File(s). Results will vary for managed services like AWS RDS. (note: need access to AWS/Azure/GCP environments where I can test against!)
125
-
-**Log File Sizes** - The size of the log files. Again, this will vary for managed services.
124
+
-**Log Directory** - Current log directory when the platform exposes it
125
+
-**Log File Sizes** - Current log file sizes when the platform exposes them
126
126
127
127
## Usage Tips
128
128
@@ -210,11 +210,14 @@ pgFirstAid is designed to be lightweight and safe to run on production systems:
210
210
- A coverage guard ensures every `check_name` in `pgFirstAid.sql` is referenced by at least one pgTAP assertion.
211
211
- Managed database validation is exercised through the reusable workflow in `.github/workflows/managed-db-validate.yml`.
212
212
213
+
> **Important:** We currently validate managed-database testing against AWS, but we do not have the funding or credits needed to keep Azure and GCP test environments running. If you have access to Azure Database for PostgreSQL or GCP Cloud SQL and want to help validate pgFirstAid there, we would be happy to have the help.
214
+
213
215
## Compatibility
214
216
215
217
-**PostgreSQL 10+** - Supported, with active automated validation focused on PostgreSQL 15-18
216
218
-**PostgreSQL 9.x** - Most features work (minor syntax adjustments may be needed)
217
219
- Works with PostgreSQL-compatible databases, including Amazon RDS, Aurora, Azure Database for PostgreSQL, GCP Cloud SQL, and self-hosted PostgreSQL
220
+
- Automated managed-database validation is active for AWS today. Azure and GCP support is best-effort until we can fund those test environments.
'Current value of shared_buffers. Recommended: ~25% of total system RAM for dedicated database servers.'as issue_description,
1476
+
current_setting('shared_buffers') as current_value,
1477
+
'No action needed if already tuned. For dedicated DB servers with 8GB+ RAM, target 25% of total RAM. Changes require a PostgreSQL restart.'as recommended_action,
where pg_size_bytes(current_setting('shared_buffers')) = pg_size_bytes('128MB');
1493
+
1494
+
-- INFO: work_mem current value
1495
+
insert into health_results
1496
+
select
1497
+
'INFO'as severity,
1498
+
'System Health'as category,
1499
+
'work_mem Setting'as check_name,
1500
+
'System'as object_name,
1501
+
'Current value of work_mem. Allocated per sort/hash operation per session — multiply by max_connections and parallel workers to estimate peak memory consumption.'as issue_description,
'For OLTP workloads, 16-32MB is a common starting point. Monitor pg_stat_statements for temp file spills to determine if higher is warranted. Use SET work_mem per-session for large one-off queries rather than setting globally.'as recommended_action,
-- MEDIUM: work_mem still at 4MB PostgreSQL default
1508
+
insert into health_results
1509
+
select
1510
+
'MEDIUM'as severity,
1511
+
'System Health'as category,
1512
+
'work_mem At Default'as check_name,
1513
+
'System'as object_name,
1514
+
'work_mem is set to the PostgreSQL default of 4MB. On modern hardware this often causes unnecessary sort and hash spills to disk.'as issue_description,
1515
+
current_setting('work_mem') as current_value,
1516
+
'Consider raising work_mem to 16-32MB for OLTP workloads. Be aware that work_mem is allocated per operation per session — high concurrency multiplies total memory usage.'as recommended_action,
where pg_size_bytes(current_setting('work_mem')) = pg_size_bytes('4MB');
1520
+
1521
+
-- INFO: effective_cache_size current value
1522
+
insert into health_results
1523
+
select
1524
+
'INFO'as severity,
1525
+
'System Health'as category,
1526
+
'effective_cache_size Setting'as check_name,
1527
+
'System'as object_name,
1528
+
'Current value of effective_cache_size. Tells the query planner how much memory is available for disk caching. Does not allocate memory — purely advisory.'as issue_description,
1529
+
current_setting('effective_cache_size') as current_value,
1530
+
'Set to ~50-75% of total system RAM (shared_buffers + expected OS page cache). Underestimates cause the planner to prefer nested loops over index scans.'as recommended_action,
'Current value of maintenance_work_mem. Used by VACUUM, CREATE INDEX, ALTER TABLE, and each autovacuum worker.'as issue_description,
1542
+
current_setting('maintenance_work_mem') as current_value,
1543
+
'Consider 256MB-1GB on modern hardware. Higher values speed up index builds and autovacuum on large tables. Changes take effect immediately for new sessions.'as recommended_action,
-- INFO: Transaction ID wraparound risk per database
1548
+
insert into health_results
1549
+
select
1550
+
'INFO'as severity,
1551
+
'System Health'as category,
1552
+
'Transaction ID Wraparound Risk'as check_name,
1553
+
datname as object_name,
1554
+
'Age of the oldest unfrozen transaction ID in this database. PostgreSQL must freeze XIDs before reaching ~2.1 billion to prevent data loss from wraparound.'as issue_description,
1555
+
datname ||': XID age '||trim(to_char(age(datfrozenxid), 'FM999,999,999,990')) ||
'Run VACUUM FREEZE on databases approaching high XID age. Ensure autovacuum is enabled and not blocked. Monitor databases with age > 500,000,000.'as recommended_action,
'Checkpoint activity since stats last reset. Forced checkpoints occur when WAL fills up before the scheduled interval — high ratios suggest max_wal_size may be too small. PG15/16 reads from pg_stat_bgwriter; PG17+ reads from pg_stat_checkpointer.'as issue_description,
1576
+
_pg_firstaid_checkpoint_stats() as current_value,
1577
+
'If forced checkpoints are consistently above 50% of total, consider increasing max_wal_size. Reset stats with: SELECT pg_stat_reset_shared('''||
1578
+
case
1579
+
when current_setting('server_version_num')::int>=170000 then 'checkpointer'
'Whether this server is operating as a primary or standby replica. Context for interpreting other checks — some checks are only relevant on standbys.'as issue_description,
'If consistently above 80%, consider a connection pooler such as PgBouncer. Reserve headroom for superuser connections (superuser_reserved_connections).'as recommended_action,
0 commit comments