Return every long-running maintenance command currently reporting progress (pg_stat_progress_vacuum, _analyze, _create_index, _cluster, _copy, _basebackup), with the phase, the blocks or tuples done against the total, a completion percentage, and how long it has been running.
read-onlyany connectionsweeps replication groupsweeps group
progressStats([pid], [relation])
Return every long-running maintenance command currently reporting progress (pg_stat_progress_vacuum, _analyze, _create_index, _cluster, _copy, _basebackup), with the phase, the blocks or tuples done against the total, a completion percentage, and how long it has been running. Use it to decide whether a VACUUM will finish before wraparound, or whether a CREATE INDEX is stuck waiting on a locker. The PostgreSQL 17 rename of the vacuum dead-tuple columns is normalized, and 'dead_tuple_unit' says whether the server counts tuples or bytes; on 17 and newer it also returns num_dead_item_ids alongside the byte counts, and indexes_total against indexes_processed -- index vacuuming is the phase a long VACUUM usually sits in, and blocks scanned alone will look stalled throughout it.
On PostgreSQL 18 and newer, delay_time_ms is the total time this vacuum has spent asleep on the cost-based delay and delay_percent is that against its elapsed time -- a vacuum that is mostly sleeping is being throttled by vacuum_cost_delay/vacuum_cost_limit and looks identical, in blocks per second, to one on a slow disk. That is the difference between raising a cost limit and buying I/O. A logical replication table sync also reports here: take the worker pid from subscriptionStats and pass it as pid.
Note that such a copy streams from the publisher rather than reading a file, so bytes_total is 0 and bytes_percent is null -- bytes_processed and tuples_processed are the figures that move.
currentActivityAlso accepts connection, replication_group, group, role, described once under arguments every tool takes.
Running commands, one array per category; always all six. An absent extension or a missing grant is reported as {error, hint} instead.
| Field | Type |
|---|---|
| analyze | array | null |
| basebackup | array | null |
| cluster | array | null |
| copy | array | null |
| create_index | array | null |
| vacuum | array | null |
This reading is instance-wide -- every database on the same postmaster returns it identically, so asking each of them in turn repeats one answer. The counters here are each server's own, so members of a replication group legitimately disagree and the answer is their sum, not the primary's copy.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "progressStats",
"arguments": {}
}
}
{
"vacuum": [
{
"pid": 60221,
"database": "shop",
"relation": "shop.orders",
"phase": "scanning heap",
"heap_blks_total": 23000,
"heap_blks_scanned": 11040,
"scanned_percent": 48.0,
"elapsed_s": 94.2
}
],
"analyze": [],
"create_index": [],
"cluster": [],
"copy": [],
"basebackup": []
}
Invented values on a fictional shop database, shaped by and checked against this tool's output schema. Real output is returned as structuredContent to clients that negotiate MCP 2025-06-18 or later.
diskUsage, databaseSize, serverSettings, currentActivity, currentLocks, databaseStats, statementStats, wraparoundStatus, ioStats, checkpointStats, tableIOStats, hostCapacity, bufferCacheSummary, bufferCacheContents