How-to · OpenTelemetry
How to Monitor PostgreSQL with OpenTelemetry
Dilip Namdev
May 2026
7 min read
Monitoring PostgreSQL with OpenTelemetry means collecting database metrics through the OpenTelemetry Collector's PostgreSQL receiver and exporting them over OTLP, so database health sits alongside application traces..
Monitoring PostgreSQL with OpenTelemetry means collecting database metrics through the OpenTelemetry Collector's PostgreSQL receiver and exporting them over OTLP, so database health sits alongside application traces.
What to observe in PostgreSQL
PostgreSQL trouble is predictable if you watch the right things: connection usage against the configured maximum, transaction throughput, the buffer-cache hit ratio, lock contention and blocked queries, replication lag on any replicas, and disk usage. The two that cause most user-facing latency are slow or blocked queries and a cache hit ratio that falls because the working set no longer fits in shared buffers.
The highest-leverage view is the one that links a slow application request to the exact statement behind it, which is why database telemetry is most useful when the query the app ran is carried on the request's trace and the database's own metrics sit alongside it.
How OpenTelemetry collects it
The OpenTelemetry Collector's postgresql receiver connects to the server as a monitoring user and reads the internal statistics views, emitting database and table-level metrics, backends, commits and rollbacks, block reads and cache hits, replication delay and database size, on an interval. For query-level detail, enable the slow-query log (log_min_duration_statement) and collect it with the filelog receiver, and enable pg_stat_statements so the worst statements are attributable.
The permission detail that catches people is the monitoring role: grant the receiver's user the pg_monitor role (or the specific stat privileges), or the statistics views return partial or empty data and the metrics look wrong. Application spans that carry the SQL statement as an attribute complete the picture by tying a query's latency to the request that issued it.
Receiver metric names follow the postgresql receiver's conventions and can vary by Collector version; confirm against your build.
Key metrics to watch
The signals that predict most PostgreSQL incidents:
| Signal | Source | What it tells you / watch for |
|---|---|---|
| postgresql.backends | postgresql receiver | Active connections. Approaching max_connections is the road to 'too many clients' errors. |
| postgresql.blocks_read vs cache hits | postgresql receiver | Compute the cache hit ratio; a falling ratio means the working set no longer fits in shared_buffers. |
| postgresql.commits / rollbacks | postgresql receiver | Transaction throughput and a rollback rate that signals application or contention problems. |
| postgresql.replication.data_delay | postgresql receiver | Replication lag on replicas; growing lag means replicas serve stale data. |
| postgresql.deadlocks | postgresql receiver | Deadlocks per database; a rising count is a contention pattern to fix. |
| postgresql.db_size | postgresql receiver | Database growth and, with disk metrics, how close you are to running out of space. |
What to put on a dashboard
A PostgreSQL dashboard should answer: are we running out of connections, is the cache still doing its job, and is anything blocked or lagging. Row one: backends against max_connections, and the cache hit ratio computed from block reads and hits. Row two: commits and rollbacks per second, deadlocks, and long-running or blocked query count. Row three: replication lag per replica and database size against disk capacity.
# connection saturation (fraction of max_connections in use) postgresql.backends / postgresql.connection.max # buffer cache hit ratio (below ~0.99 on OLTP is worth investigating) cache_hits / (cache_hits + postgresql.blocks_read) # replication lag per replica postgresql.replication.data_delay by (replica)Reading the signals: common failure modes
Connection exhaustion
Applications start receiving 'too many clients already' and latency spikes as requests wait for a connection. postgresql.backends sits at the ceiling. The cause is usually a missing or undersized connection pooler (PgBouncer) or a leak of unclosed connections; pool in front of Postgres rather than raising max_connections indefinitely.
Cache hit ratio dropping
Read latency rises and disk I/O climbs because queries are hitting disk instead of shared buffers. The hit ratio computed from block reads and hits falls below its normal high-nineties. Either the working set has outgrown shared_buffers, or a query is scanning far more data than it should, findable via pg_stat_statements.
Lock contention and blocked queries
Some queries hang while others proceed, because a long transaction holds a lock the others need. Blocked-query count and lock waits rise, and deadlocks may appear. Find the blocking transaction and the statement holding the lock; the usual root cause is a long-running write transaction or a missing index forcing broad locks.
Example alert conditions
Starting thresholds to tune:
| Condition | Signal | Meaning |
|---|---|---|
| backends / max_connections > 0.85 for 5m | connections | Running out of connections. |
| cache hit ratio < 0.95 for 15m | cache | Working set spilling to disk; latency rising. |
| replication data_delay > 30s for 5m | replication | Replicas serving increasingly stale data. |
| deadlocks increasing over 10m | contention | A contention pattern is developing. |
From monitoring to autonomous resolution
Opstral's Telemetry Ops ingests PostgreSQL telemetry over OpenTelemetry, and its Data Ops and Sentinel capabilities resolve database incidents, a lock storm, a runaway query, replication lag, through governed Action Tickets. Explore Telemetry Ops and Data Ops.
Frequently asked questions
How do I monitor PostgreSQL with OpenTelemetry?
Use the OpenTelemetry Collector's postgresql receiver to collect database metrics and the filelog receiver for logs, exported over OTLP, and correlate with application spans.
What are the key PostgreSQL metrics to watch?
Connection usage against limits, cache hit ratio, replication lag, lock contention and long-running queries, transaction throughput, and disk usage.