A lightweight, intelligent PostgreSQL extension for database health monitoring and maintenance. Provides actionable insights through JSON-formatted metrics on table bloat, index efficiency, materialized view performance, and more.
c77_dbh embeds health monitoring directly into your PostgreSQL database, eliminating the need for external monitoring tools. It uses statistical analysis to establish dynamic, database-specific thresholds for various health indicators, enabling both technical and non-technical users to identify and address performance issues.
Tracks table bloat with context-aware thresholds and TOAST overhead detection
Identifies unused or bloated indexes with efficiency metrics and specific recommendations
Monitors refresh times and bottlenecks (I/O, CPU, memory) with historical trending
Automatically leverages pgstattuple and pg_stat_statements when available, with graceful fallbacks
Provides clear status indicators (Red/Yellow/Green), severity scores (1-5), and actionable recommendations
Structured JSON format ideal for integration with monitoring dashboards
Minimal impact on database performance with configurable collection frequencies
pgstattuple
extension for precise bloat measurementspg_stat_statements
extension for enhanced query performance insightspg_cron
extension for automated statistics collectionAfter installation, enable the extension in your database:
CREATE EXTENSION c77_dbh;
Initialize the statistics tables:
-- Update table and vacuum statistics
SELECT c77_dbh_update_vacuum_stats();
-- Update index statistics (including TOAST indexes)
SELECT c77_dbh_update_index_stats();
Query health metrics:
-- Table health with bloat estimates and recommendations
SELECT * FROM c77_dbh_get_vacuum_health();
-- Index health analysis
SELECT * FROM c77_dbh_get_index_health();
-- TOAST index specific analysis
SELECT * FROM c77_dbh_get_toast_health();
-- Materialized view refresh performance
SELECT * FROM c77_dbh_get_mv_health();
With pg_cron
extension:
-- Update vacuum stats hourly
SELECT cron.schedule('update_vacuum_stats', '0 * * * *',
'SELECT c77_dbh_update_vacuum_stats()');
-- Update index stats hourly
SELECT cron.schedule('update_index_stats', '0 * * * *',
'SELECT c77_dbh_update_index_stats()');
Database Characteristics | Recommended Update Frequency |
---|---|
Mixed read/write | Every 6 hours |
Read-heavy, stable | Daily |
Development/staging | On-demand or daily |
The JSON output format makes integration with monitoring dashboards straightforward:
Use a PostgreSQL data source with JSON parsing to create rich visualizations
Import as custom metrics for comprehensive database monitoring
Use the structured JSON for consistency across different monitoring platforms
-- Grant read access to a reporting role
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reporting_role;
-- Grant full access to admin roles
GRANT ALL ON ALL TABLES IN SCHEMA public TO admin_role;
# Include in schema backups
pg_dump -s -n public mydatabase > schema.sql
The extension consists of:
c77_dbh_update_vacuum_stats()
, c77_dbh_update_index_stats()
c77_dbh_get_vacuum_health()
, c77_dbh_get_index_health()
-- Example materialized view health output
{
"metric": "Materialized View Performance",
"view_name": "public.sales_summary",
"status": "Yellow",
"severity": 3,
"insight": "Refresh times trending upward; consider optimization",
"action": "Review refresh query performance and consider incremental refresh",
"last_refresh": "2025-06-12 08:30:15",
"refresh_duration": "00:03:42",
"rows_affected": 1234567,
"trend": "increasing",
"details": {
"avg_refresh_time": "00:02:45",
"max_refresh_time": "00:05:12",
"bottleneck": "I/O intensive operations"
}
}
The extension uses statistical process control principles to establish intelligent thresholds:
Health issues are scored on a 1-5 scale:
-- Optimize statistics collection for large databases
-- The extension automatically uses sampling for large tables
-- Check collection performance
SELECT
table_name,
collection_time,
sample_size,
accuracy_estimate
FROM c77_dbh_collection_stats
ORDER BY collection_time DESC;
Ensure statistics collection has been run:
-- Check if statistics have been collected
SELECT COUNT(*) FROM c77_dbh_vacuum_stats;
SELECT COUNT(*) FROM c77_dbh_index_stats;
-- If empty, run collection manually
SELECT c77_dbh_update_vacuum_stats();
SELECT c77_dbh_update_index_stats();
-- Query for Grafana visualization
SELECT
table_name,
CASE status
WHEN 'Red' THEN 3
WHEN 'Yellow' THEN 2
WHEN 'Green' THEN 1
END as status_code,
severity,
insight
FROM c77_dbh_get_vacuum_health()
WHERE status != 'Green'
ORDER BY severity DESC;
-- Query for alerting systems
SELECT
'Database Health Alert' as alert_type,
table_name,
status,
severity,
insight,
action,
NOW() as alert_time
FROM c77_dbh_get_vacuum_health()
WHERE severity >= 4
UNION ALL
SELECT
'Index Health Alert',
index_name,
status,
severity,
insight,
action,
NOW()
FROM c77_dbh_get_index_health()
WHERE severity >= 4;
-- Clean up old statistics (older than 30 days)
DELETE FROM c77_dbh_vacuum_stats
WHERE collected_at < NOW() - INTERVAL '30 days';
DELETE FROM c77_dbh_index_stats
WHERE collected_at < NOW() - INTERVAL '30 days';
Intelligent database health monitoring made simple!
This extension brings enterprise-grade database monitoring directly into PostgreSQL, providing actionable insights without the complexity of external tools.