Understand
Mental model
Treat PostgreSQL as a set of cooperating loops rather than a black box. Client backends execute work, shared buffers reduce physical reads, WAL makes changes durable, checkpoints bound recovery work, and vacuum makes old row versions reusable. Health means these loops keep pace with the workload without creating queues that grow indefinitely.
Calibrate
What healthy usually looks like
- Connection demand remains comfortably below the configured limit.
- Transaction rollbacks, deadlocks, temporary files, and physical reads have explanations in the workload.
- Background maintenance completes often enough that dead rows and transaction ID age remain bounded.
Observe
Ask the database a bounded question
Diagnostic query
Read the database-level counters
Establish a compact baseline for connections, transaction outcomes, cache activity, temporary files, and deadlocks in the current database.
SELECT
now() AS observed_at,
numbackends AS current_backends,
xact_commit,
xact_rollback,
blks_read,
blks_hit,
temp_files,
pg_size_pretty(temp_bytes) AS temporary_bytes,
deadlocks
FROM pg_stat_database
WHERE datname = current_database();The selected columns are available in supported PostgreSQL 14–18 releases.
Interpret
Read the output
- Start with change over time. Most statistics views expose cumulative counters that reset after a statistics reset or some unclean starts.
- Separate saturation from work. High CPU with stable latency is different from high CPU plus growing runnable queues and latency.
- Correlate database evidence with operating-system CPU, memory, storage latency, and network evidence.
Avoid
Common traps
- Treating one ratio—especially cache hit rate—as a complete health score.
- Changing several configuration parameters before establishing which resource or queue is constrained.
- Ignoring the age and reset time of cumulative statistics.
Verify
Check your reasoning
Continue
Related runbooks
Verify independently