Skip to main content
View rawEdit

Table metrics

Table-level statistics from pg_stat_user_tables and related views.

Data sources​

ViewDescription
pg_stat_user_tablesTable access statistics
pg_statio_user_tablesTable I/O statistics
pg_classTable sizes and properties

Core metrics​

Access metrics​

MetricTypeDescription
pg_stat_user_tables_seq_scan_totalCounterSequential scans initiated
pg_stat_user_tables_seq_tup_read_totalCounterRows fetched by sequential scans
pg_stat_user_tables_idx_scan_totalCounterIndex scans initiated
pg_stat_user_tables_idx_tup_fetch_totalCounterRows fetched by index scans

Modification metrics​

MetricTypeDescription
pg_stat_user_tables_n_tup_ins_totalCounterRows inserted
pg_stat_user_tables_n_tup_upd_totalCounterRows updated
pg_stat_user_tables_n_tup_del_totalCounterRows deleted
pg_stat_user_tables_n_tup_hot_upd_totalCounterHOT updates (heap-only tuple)

Tuple metrics​

MetricTypeDescription
pg_stat_user_tables_n_live_tupGaugeEstimated live rows
pg_stat_user_tables_n_dead_tupGaugeEstimated dead rows
pg_stat_user_tables_n_mod_since_analyzeGaugeRows modified since last analyze

Vacuum metrics​

MetricTypeDescription
pg_stat_user_tables_last_vacuumGaugeTimestamp of last manual vacuum
pg_stat_user_tables_last_autovacuumGaugeTimestamp of last autovacuum
pg_stat_user_tables_last_analyzeGaugeTimestamp of last manual analyze
pg_stat_user_tables_last_autoanalyzeGaugeTimestamp of last autoanalyze
pg_stat_user_tables_vacuum_count_totalCounterManual vacuum count
pg_stat_user_tables_autovacuum_count_totalCounterAutovacuum count

Size metrics​

MetricTypeDescription
pg_table_size_bytesGaugeTable size (excluding indexes)
pg_total_relation_size_bytesGaugeTotal size (table + indexes + toast)
pg_indexes_size_bytesGaugeTotal index size for table

I/O metrics​

MetricTypeDescription
pg_statio_user_tables_heap_blks_read_totalCounterHeap blocks read from disk
pg_statio_user_tables_heap_blks_hit_totalCounterHeap blocks hit in buffer cache
pg_statio_user_tables_idx_blks_read_totalCounterIndex blocks read from disk
pg_statio_user_tables_idx_blks_hit_totalCounterIndex blocks hit in buffer cache

Labels​

LabelDescriptionExample
relnameTable nameusers
schemanameSchema namepublic
datnameDatabase namemyapp
cluster_nameCluster identifierproduction
node_nameNode identifierprimary

Common queries​

Sequential scan ratio​

rate(pg_stat_user_tables_seq_scan_total[5m])
/
(
rate(pg_stat_user_tables_seq_scan_total[5m])
+
rate(pg_stat_user_tables_idx_scan_total[5m])
)

Tables with high dead tuple ratio​

pg_stat_user_tables_n_dead_tup
/
(pg_stat_user_tables_n_live_tup + pg_stat_user_tables_n_dead_tup)
> 0.1

HOT update ratio​

rate(pg_stat_user_tables_n_tup_hot_upd_total[5m])
/
rate(pg_stat_user_tables_n_tup_upd_total[5m])

Tables not vacuumed recently​

time() - pg_stat_user_tables_last_autovacuum > 86400

Buffer hit ratio per table​

rate(pg_statio_user_tables_heap_blks_hit_total[5m])
/
(
rate(pg_statio_user_tables_heap_blks_hit_total[5m])
+
rate(pg_statio_user_tables_heap_blks_read_total[5m])
)

Largest tables​

topk(10, pg_total_relation_size_bytes)

Write-heavy tables​

topk(10,
rate(pg_stat_user_tables_n_tup_ins_total[5m])
+
rate(pg_stat_user_tables_n_tup_upd_total[5m])
+
rate(pg_stat_user_tables_n_tup_del_total[5m])
)

Dashboard usage​

These metrics are used in:

Interpreting metrics​

Sequential vs index scans​

High sequential scan rate on large tables suggests missing indexes:

select
schemaname,
relname,
seq_scan,
idx_scan,
pg_size_pretty(pg_relation_size(relid)) as size
from pg_stat_user_tables
where seq_scan > idx_scan
and pg_relation_size(relid) > 10000000
order by seq_scan desc;

Dead tuple accumulation​

Dead tuples indicate rows deleted/updated but not yet vacuumed:

select
relname,
n_live_tup,
n_dead_tup,
round(100.0 * n_dead_tup / nullif(n_live_tup + n_dead_tup, 0), 1) as dead_pct,
last_autovacuum
from pg_stat_user_tables
where n_dead_tup > 1000
order by n_dead_tup desc;

HOT update efficiency​

HOT updates avoid index updates — higher ratio is better:

select
relname,
n_tup_upd,
n_tup_hot_upd,
round(100.0 * n_tup_hot_upd / nullif(n_tup_upd, 0), 1) as hot_pct
from pg_stat_user_tables
where n_tup_upd > 1000
order by n_tup_upd desc;

Troubleshooting​

Metrics show stale values​

Table statistics are cumulative since last stats reset:

select stats_reset from pg_stat_database where datname = current_database();

Size metrics not matching disk​

pg_table_size excludes TOAST and indexes. Use pg_total_relation_size for complete size.

Missing tables in metrics​

Verify tables are in user schemas (not system catalogs):

select relname from pg_stat_user_tables where schemaname = 'public';