Integration · PostgreSQL

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.
Obseria apps and capabilities: observability, APM, infrastructure and integrations
Obseria home dashboard with service health, open problems, SLO compliance and ingestion
Obseria trace explorer with span list and span attributes
Overview

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.

Coverage

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.
At a glance

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.

  • postgresql.backends
  • postgresql.connection.max

Speed and transactions

Tells you how much work is completed successfully, how much is cancelled and how often data comes from fast memory.

  • postgresql.commits
  • postgresql.rollbacks
  • postgresql.blks_hit

Replication and safety

Reveals whether backup copies of your data are up to date, so a failover does not lose recent changes.

  • postgresql.replication.data_delay
  • postgresql.wal.lag

Upkeep and growth

Highlights blocking conflicts, routine cleanup and database growth, helping you plan storage and avoid slowdowns.

  • postgresql.deadlocks
  • postgresql.table.vacuum.count
  • postgresql.db_size
Show all 10 metrics in detail
MetricUnitWhat it tells you
postgresql.backends1Open connections per database; compare with max_connections to catch pool exhaustion.
postgresql.connection.max{connections}Configured max_connections, the ceiling for backends.
postgresql.commits1Committed transactions, the basic throughput signal of a database.
postgresql.rollbacks1Rolled 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_delayByBytes of WAL a replica has not yet applied.
postgresql.wal.lagsTime 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_sizeByDisk space used per database, for capacity planning and growth alerts.
Setup

Set up PostgreSQL monitoring in minutes

  1. 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.

  2. 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.

  3. 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.

Example configuration · YAML
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
Guide

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.deadlocks and postgresql.database.locks and set log_lock_waits = on.
  • Slow queries: a missing index turns into sequential scans. Set log_min_duration_statement, enable the pg_stat_statements extension, 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

  1. Use a dedicated role with pg_monitor instead of a superuser for metric collection.
  2. Monitor primary and every replica separately and tag them with their role.
  3. Alert on symptoms first (connection saturation, replication lag, error rate), then on causes.
  4. Keep query text in spans sanitized; OpenTelemetry instrumentations replace literals with placeholders by default in most languages, and Obseria Pipeline can mask remaining values.
  5. 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.

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.