Monitor Database Index Bloat in Python
Simulates index bloat checks for database tables using random ratio thresholds and reports alerts per index.
Python code
37 linesimport random
import time
class IndexBloatMonitor:
def __init__(self, thresholds=(0.5, 0.8, 0.9)):
self.thresholds = thresholds
self.indices = {
"users_pk": 48.2,
"orders_created_idx": 124.7,
"products_name_idx": 15.3,
"payments_user_idx": 203.9,
}
def _simulate_bloat(self):
for key in self.indices:
self.indices[key] += random.uniform(0.1, 2.5)
def check(self):
self._simulate_bloat()
alerts = []
for name, size in self.indices.items():
bloat_ratio = random.uniform(0.0, 1.0)
status = "healthy"
if bloat_ratio > self.thresholds[2]:
status = "critical"
elif bloat_ratio > self.thresholds[1]:
status = "warning"
elif bloat_ratio > self.thresholds[0]:
status = "monitor"
alerts.append((name, size, bloat_ratio, status))
return alerts
if __name__ == "__main__":
monitor = IndexBloatMonitor()
for index_name, size_mb, bloat, level in monitor.check():
print(f"{index_name}: {size_mb:.1f} MB, bloat {bloat:.0%} -> {level.upper()}")
Output
users_pk: 49.8 MB, bloat 62% -> MONITOR
orders_created_idx: 126.1 MB, bloat 41% -> MONITOR
products_name_idx: 17.2 MB, bloat 18% -> HEALTHY
payments_user_idx: 205.4 MB, bloat 95% -> CRITICAL
How it works
The _simulate_bloat method updates each index size with a random growth value to mimic data accumulation. The check method generates a random bloat ratio per index and compares it against configurable thresholds — monitor, warning, and critical. Alerts are collected as tuples of index name, size, bloat ratio, and status. The script prints formatted output for each index, including the bloat percentage and alert level, making it easy to spot problematic indexes at a glance.
Common mistakes
- Using fixed thresholds without tuning them to your database workload and index characteristics.
- Assuming bloat percentages are exact metrics rather than simulated values in this mock.
- Not resetting or persisting index state between check runs, which makes monitoring non-reproducible.
- Ignoring that higher size doesn't always mean higher bloat — the ratio matters separately.
Variations
- Replace random bloat simulation with actual `pgstatindex` queries in PostgreSQL for real monitoring.
- Add an email or webhook alert when a critical bloat level is detected.
Real-world use cases
- Scheduling a nightly job that checks index bloat on large tables and pages DBAs about rebuild candidates.
- Monitoring time-series tables where indexes degrade quickly due to heavy insert/update patterns.
- Integrating bloat checks into a database health dashboard that flags indexes needing REINDEX or VACUUM in production.
Sponsored
More from Database scaling & optimization
- Approximate Count with HyperLogLog in Python medium
- B-Tree Insert and In-Order Traversal in Python hard
- Broadcast a Small Reference Table in Python easy
- Build a Full Text Search Index in Python medium
- Build a Partial Index Mock in Python for Database Filtering easy
- Composite index leftmost prefix in Python medium
Keep learning
Related tutorials and quizzes for this topic.