How to Analyze Table Bloat with MCP-PostgreSQL-Ops: Tools and Usage Guide
MCP-PostgreSQL-Ops provides two dedicated MCP tools—get_table_bloat_analysis and get_database_bloat_overview—that query pg_stat_user_tables to calculate dead-tuple ratios, estimate wasted space, and recommend VACUUM operations.
The call518/mcp-postgresql-ops repository exposes specialized database maintenance utilities through the Model Context Protocol (MCP). If you need to analyze table bloat with MCP-PostgreSQL-Ops, the toolkit offers precise instrumentation for identifying storage inefficiencies caused by dead tuples across individual tables or entire schemas.
Available Bloat Analysis Tools
Two primary functions handle bloat detection in src/mcp_postgresql_ops/mcp_main.py:
get_table_bloat_analysis: Located at line 1887, this tool calculates per-table bloat ratios by comparing dead tuples against live tuples in pg_stat_user_tables. It returns metrics including bloat_ratio_percent, estimated_bloat_size, and vacuum recommendations.
get_database_bloat_overview: Found at line 2140, this function aggregates bloat statistics across all non-system schemas. It summarizes total_dead_tuples, overall_bloat_percent, and identifies never_vacuumed_tables at the schema level.
Both tools are decorated with @mcp.tool() and automatically register with the MCP server upon startup. Helper utilities in src/mcp_postgresql_ops/functions.py handle query execution and result formatting, while src/mcp_postgresql_ops/prompt_template.md documents these tools for LLM discovery.
How to Analyze Table Bloat
Via Natural Language Prompts
When running the MCP server, invoke the tools through conversational queries. The MCP engine parses your intent and routes to the appropriate function.
Example prompts:
- Analyze table bloat for tables with more than 5000 dead tuples in the public schema of the inventory database.
- Show a database-wide bloat summary for the ecommerce database.
The server executes the underlying async function and returns formatted markdown tables showing bloat metrics.
Via Direct Function Calls
For custom Python integrations, import and call the async functions directly:
import asyncio
from mcp_postgresql_ops.mcp_main import get_table_bloat_analysis, get_database_bloat_overview
async def analyze_bloat():
# Detailed table analysis
table_report = await get_table_bloat_analysis(
database_name="inventory",
schema_name="public",
min_dead_tuples=5000,
limit=30
)
print(table_report)
# Database-wide overview
db_report = await get_database_bloat_overview(
database_name="ecommerce",
limit=10
)
print(db_report)
asyncio.run(analyze_bloat())
Key Parameters
Both functions accept these arguments:
database_name: Target database (defaults toPOSTGRES_DBenvironment variable)schema_name: Filter to specific schema (omitted scans all non-system schemas)table_pattern: SQLLIKEpattern for table name filtering (e.g.,'%log%')min_dead_tuples: Threshold for inclusion (set to1to show all bloat)limit: Maximum results (1-100 for tables, 1-50 for schemas)
System schemas (information_schema, pg_catalog, pg_%) are automatically excluded.
Interpreting Bloat Analysis Results
The tools utilize format_table_data() from src/mcp_postgresql_ops/functions.py to render structured output.
Table-level metrics include:
schema_nameandtable_nametotal_size/table_size(human-readable)dead_tuplesvslive_tuplescountsbloat_ratio_percent: Calculated as (dead tuples / total tuples) × 100estimated_bloat_size: Human-readable wasted space estimatevacuum_status: Indicates "Never vacuumed" or "Manual vacuum needed"
Database-level overview provides:
total_tablesandtables_with_bloatcountstotal_dead_tuplesacross the schemaoverall_bloat_percentandestimated_total_bloatnever_vacuumed_tablesrequiring immediate attention
Advanced Filtering Examples
Filter by table name pattern to isolate specific workloads:
await get_table_bloat_analysis(
database_name="ecommerce",
table_pattern="user_%", # Matches user_logs, user_sessions
min_dead_tuples=100,
limit=20
)
This queries only tables matching the SQL LIKE pattern while respecting the minimum dead tuple threshold.
Summary
- MCP-PostgreSQL-Ops exposes
get_table_bloat_analysisandget_database_bloat_overviewinsrc/mcp_postgresql_ops/mcp_main.pyto analyze table bloat via dead-tuple ratios. - Both tools exclude system schemas automatically and support filtering by
schema_name,table_pattern, andmin_dead_tuples. - Results include
bloat_ratio_percent,estimated_bloat_size, and vacuum status indicators formatted as markdown tables. - You can invoke these through natural language prompts handled by the MCP server or direct async Python function calls.
Frequently Asked Questions
What PostgreSQL statistics do the bloat tools query?
The tools query pg_stat_user_tables to obtain live and dead tuple counts, then calculate ratios and estimate wasted space based on table sizes. This approach avoids the performance overhead of pgstattuple while providing actionable bloat estimates.
Can I analyze bloat in specific schemas only?
Yes. Pass the schema_name parameter to restrict analysis to a single schema. If omitted, the tools scan all non-system schemas (excluding information_schema, pg_catalog, and pg_% patterns).
What is the difference between table-level and database-wide bloat analysis?
get_table_bloat_analysis provides granular per-table metrics including individual vacuum status and precise bloat ratios, while get_database_bloat_overview aggregates statistics at the schema level to show total dead tuples, overall bloat percentages, and counts of never-vacuumed tables.
Do the tools require superuser privileges?
The tools require read access to pg_stat_user_tables and pg_class, which are typically available to all users. However, viewing size statistics for all schemas may require appropriate privileges or membership in the pg_read_all_stats role depending on your PostgreSQL configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →