PostgreSQL monitoring: performance, replication and queries
Track connections, cache hit ratio, locks, vacuum and replication lag for every Postgres instance, and see which service and which query cause the load.


Why monitor PostgreSQL with Obseria
From query to caller
Database spans from OpenTelemetry instrumentation show which endpoint ran a slow statement, so you fix the code path, not just the index.
Replication you can trust
WAL lag and replication delay per replica, with alerts before read replicas serve stale data or a failover loses writes.
Self-hosted and managed
The same views for PostgreSQL on VMs, in Kubernetes, on Amazon RDS and Aurora, Azure Database and Cloud SQL.
PostgreSQL components Obseria monitors
- Databases. Size, commits, rollbacks, block reads, deadlocks and row operations per database from pg_stat_database.
- Tables and indexes. Table and index size, index scans, sequential scans and vacuum counts per table.
- Connections. Backends per database compared with max_connections, so pool exhaustion is visible early.
- Replication and WAL. Replication data delay in bytes, WAL lag and WAL age for every standby.
- Background writer and checkpoints. Checkpoint counts, buffers written and checkpoint duration from pg_stat_bgwriter.
- Logs and queries. PostgreSQL logs including slow statements via the filelog receiver, plus client-side database spans.
The PostgreSQL signals that matter
Obseria collects these values automatically and shows them in ready-made dashboards and alerts.Connections and load
Shows how many users and applications are connected and how close the database is to turning new ones away.
Speed and transactions
Tells you how much work is completed successfully, how much is cancelled and how often data comes from fast memory.
Replication and safety
Reveals whether backup copies of your data are up to date, so a failover does not lose recent changes.
Upkeep and growth
Highlights blocking conflicts, routine cleanup and database growth, helping you plan storage and avoid slowdowns.
Show all 10 metrics in detail
| Metric | Unit | What it tells you |
|---|---|---|
postgresql.backends | 1 | Open connections per database; compare with max_connections to catch pool exhaustion. |
postgresql.connection.max | {connections} | Configured max_connections, the ceiling for backends. |
postgresql.commits | 1 | Committed transactions, the basic throughput signal of a database. |
postgresql.rollbacks | 1 | Rolled back transactions; a rising share points to application errors or conflicts. |
postgresql.blks_hit | {blks_hit} | Blocks found in shared buffers; with blocks read it gives the cache hit ratio. |
postgresql.deadlocks | {deadlock} | Deadlocks detected per database; any steady increase needs investigation. |
postgresql.replication.data_delay | By | Bytes of WAL a replica has not yet applied. |
postgresql.wal.lag | s | Time between WAL being written on the primary and flushed or replayed on a standby. |
postgresql.table.vacuum.count | {vacuum} | Vacuum runs per table; tables that are never vacuumed accumulate bloat. |
postgresql.db_size | By | Disk space used per database, for capacity planning and growth alerts. |
Set up PostgreSQL monitoring in minutes
- Step 1
Create a monitoring user
Create a read-only role and grant it pg_monitor, so it can read the statistics views without access to your data.
- Step 2
Configure the postgresql receiver
Add the receiver to the OpenTelemetry Collector or Obseria Agent with endpoint, credentials from environment variables and the databases to watch.
- Step 3
Add traces and logs
Instrument the calling services with OpenTelemetry and ship PostgreSQL logs, so slow queries link to requests and log lines.
receivers:
postgresql:
endpoint: db-primary:5432
transport: tcp
username: otel_monitor
password: ${env:POSTGRESQL_PASSWORD}
databases: [orders, billing]
collection_interval: 30s
tls:
insecure: false
ca_file: /etc/otel/pg-ca.crt
metrics:
postgresql.deadlocks:
enabled: true
postgresql.blks_hit:
enabled: true
exporters:
otlphttp:
endpoint: ${env:OBSERIA_OTLP_ENDPOINT}
headers:
Authorization: "Bearer ${env:OBSERIA_TOKEN}"
service:
pipelines:
metrics:
receivers: [postgresql]
exporters: [otlphttp]
Out of the box
Dashboards, alerts and SLOs that are ready the moment data arrives.
- PostgreSQL instance overview: connections, TPS, cache hit ratio
- Replication lag per standby
- Table and index size, scans and vacuum activity
- Alert: backends above 80% of max_connections
- Alert: replication delay or deadlocks increasing
PostgreSQL monitoring: what matters
Why PostgreSQL monitoring matters
PostgreSQL is the system of record for many applications: orders, accounts, inventory. When it slows down, every service that depends on it slows down with it, and the symptom usually appears far away as a timeout in an API or a failing background job. PostgreSQL monitoring has to answer three questions quickly: is the database itself healthy, is it under unusual load, and which workload causes that load.
Obseria collects Postgres metrics with the postgresql receiver of the OpenTelemetry Collector, which reads the built-in statistics views such as pg_stat_database, pg_stat_bgwriter and pg_stat_replication. Combined with database spans from your applications, every metric has a caller attached.
The PostgreSQL metrics that matter
Connections
Each connection is a backend process with its own memory. postgresql.backends compared with postgresql.connection.max shows how close you are to refusing new clients. Many idle connections usually mean a misconfigured pool; many active ones mean real load or blocking.
Throughput and errors
postgresql.commits and postgresql.rollbacks give transactions per second and the share of failed transactions. Sudden rollback spikes often follow a deployment that introduced constraint violations or serialization failures.
Cache efficiency
The cache hit ratio is blks_hit / (blks_hit + blks_read). For OLTP workloads it typically stays very high; a falling ratio means the working set no longer fits into shared_buffers and queries go to disk.
Replication and WAL
postgresql.replication.data_delay and postgresql.wal.lag show how far each standby is behind. High lag means stale reads on replicas and a larger risk of losing writes during failover.
Vacuum and bloat
MVCC leaves dead tuples behind that autovacuum must clean up. postgresql.table.vacuum.count together with table size trends reveals tables where autovacuum cannot keep up.
Common problems and how to detect them
- Connection exhaustion: backends approach max_connections and clients fail with "too many clients". Alert at 80% and check the pool settings of the calling services.
- Lock contention and deadlocks: long-running transactions block others. Enable
postgresql.deadlocksandpostgresql.database.locksand setlog_lock_waits = on. - Slow queries: a missing index turns into sequential scans. Set
log_min_duration_statement, enable thepg_stat_statementsextension, and use database spans to see which endpoint issues the statement. - Replication lag: heavy write bursts or a saturated replica disk. Correlate lag with commit rate and replica I/O.
- Table bloat and transaction ID wraparound: tables that are rarely vacuumed grow and, in the worst case, force an emergency vacuum. Watch vacuum counts and table size per table.
Best practices for PostgreSQL monitoring
- Use a dedicated role with
pg_monitorinstead of a superuser for metric collection. - Monitor primary and every replica separately and tag them with their role.
- Alert on symptoms first (connection saturation, replication lag, error rate), then on causes.
- Keep query text in spans sanitized; OpenTelemetry instrumentations replace literals with placeholders by default in most languages, and Obseria Pipeline can mask remaining values.
- Track database size and growth to plan storage before disks fill up.
How Obseria helps with PostgreSQL monitoring
Obseria brings Postgres metrics, logs and the database spans of your services into one data model in Obseria Lake. TopoGraph shows which services depend on which database, so an alert on replication lag or connection saturation immediately shows the affected applications. Obseria Intelligence correlates a slowdown with deployments, query patterns and host metrics such as disk latency, and presents the likely root cause with a chain of evidence. For managed services such as Amazon RDS, Azure Database for PostgreSQL or Cloud SQL, the agentless cloud integrations add provider metrics without any agent on the database host.
Dashboards, alerts and SLOs are included. You can query everything with OQL, PromQL or SQL, for example to compare the p95 latency of database spans per statement before and after a release.
Related integrations
Related capabilities
Database Monitoring
Find the slow query behind a slow endpoint. Obseria links database metrics, query performance and logs to the traces and services that call them.
Learn moreDistributed Tracing
Follow each request across services, queues and databases with OpenTelemetry-native distributed tracing, and find the slow span or failing dependency in seconds.
Learn moreAnomaly Detection
Obseria Intelligence learns the normal rhythm of every service, flags real deviations instead of threshold noise and groups related anomalies into one problem with a probable root cause.
Learn moreLearn more
The four golden signals: latency, traffic, errors and saturation
The four golden signals explained: latency, traffic, errors and saturation, how they relate to the RED and USE methods, and how to measure them with OTel.
What is root cause analysis (RCA)?
What is root cause analysis? The RCA process for software incidents, 5 Whys, fishbone and fault tree methods, a worked example and how AI speeds up RCA.
PostgreSQL monitoring FAQ
The OpenTelemetry postgresql receiver reads standard statistics views that are available in all currently maintained PostgreSQL versions. Managed offerings such as Amazon RDS, Aurora PostgreSQL, Azure Database for PostgreSQL and Cloud SQL work as well.
A read-only role with the built-in pg_monitor role is sufficient. It can read statistics views but not your table data.
Combine three sources: database spans from OpenTelemetry instrumentation in your services, PostgreSQL logs with log_min_duration_statement, and the pg_stat_statements extension for aggregate statistics.
Yes. The receiver reports postgresql.replication.data_delay in bytes and postgresql.wal.lag in seconds per standby, and you can alert on both.
Most OpenTelemetry database instrumentations sanitize literals by default. Obseria Pipeline can additionally mask sensitive values at ingest before anything is stored.
Start monitoring PostgreSQL today
Connect PostgreSQL in minutes with OpenTelemetry or the Obseria Agent. Free for 14 days.