PostgreSQL
Collect PostgreSQL server metrics and get curated dashboards and alerts for them with a single import.
PostgreSQL is scraped by an OpenTelemetry Collector running the postgresql
receiver, which exports over OTLP to your LeanSignal agent gateway (one per
cluster or environment) — never to a remote or third-party endpoint. The gateway
keeps full fidelity locally and forwards only the demanded subset to your
dataplane. Run one collector that can reach the database; it scrapes backends,
commits/rollbacks, cache hits, tuple operations, sizes, and replication.
Metric names follow the standard OTLP → Prometheus normalization (dots become
underscores, unit/_total suffixes are added), so postgresql.commits becomes
postgresql_commits_total and postgresql.db_size becomes
postgresql_db_size_bytes. The demands below are built against those names.
Prerequisites
Section titled “Prerequisites”- A LeanSignal agent gateway deployed and connected — one per cluster or
environment. If you haven’t deployed it yet, follow
Install the agent (source:
LeanSignal/leansignal-agent). It should show as Connected under Agents in the LeanSignal app. - Network reachability to the gateway’s OTLP port —
4317(gRPC) or4318(HTTP). See Agent configuration. - An OpenTelemetry Collector that can reach your PostgreSQL server, plus a monitoring database user — both configured in Setup.
- Editor or admin role in the LeanSignal app (importing a demand creates dashboards and alert rules).
Run an OpenTelemetry Collector (for example otel/opentelemetry-collector-contrib)
with the postgresql receiver, exporting OTLP to your LeanSignal agent gateway —
not a SaaS endpoint.
Database user and grants (PostgreSQL 10+):
CREATE USER otel WITH PASSWORD 'REDACTED';GRANT pg_monitor TO otel; -- read pg_stat_* / pg_statio_* viewsThe receiver opens one connection per database it scrapes; pg_monitor (a
default role since PG10) grants read access to the statistics views it needs.
Ensure pg_hba.conf allows the collector host to connect.
receivers: postgresql: endpoint: postgres:5432 username: otel password: ${env:POSTGRES_PASSWORD} databases: [mydb] # list DBs to scrape; empty = all non-template DBs collection_interval: 30s tls: insecure: true # set false + ca_file to verify the server cert # Extended demand also needs these opt-in metrics enabled: # metrics: # postgresql.deadlocks: { enabled: true } # postgresql.temp_files: { enabled: true } # postgresql.sequential_scans: { enabled: true }
processors: resourcedetection: detectors: [env, system] system: { hostname_sources: [os] } batch: {}
exporters: otlp: endpoint: leansignal-agent:4317 # per-cluster gateway (use :4318 for HTTP) tls: insecure: true # in-cluster plaintext; provide ca_file for TLS
service: pipelines: metrics: receivers: [postgresql] processors: [resourcedetection, batch] exporters: [otlp]Logs and traces
Section titled “Logs and traces”A database server produces logs, and its traces come from the clients:
- Server logs — point a collector
filelogreceiver at the PostgreSQL log directory (log_destination = stderrwithlogging_collector = on) and forward OTLP to the gateway; the receiver can run on the gateway itself if it can read the files. Already shipping them with a Promtail/Alloy-style agent? Repoint it at the gateway’s Loki push endpoint (:3500) instead. - Query traces — instrument the applications that call PostgreSQL (see
the runtime integrations); their database client spans
carry
db.*attributes, so slow statements show up inside request traces.
Demands
Section titled “Demands”PostgreSQL ships as a ready-made demand in three variants. You don’t copy any JSON — in the LeanSignal app go to Demands, press the ˅ arrow on the Add Demand button (the arrow opens the import menu), choose Import from catalog…, and pick the variant. Each variant below lists the slug that identifies its published bundle. See Integrations for the full import flow.
The variants are nested — Standard is a superset of Essential, Extended a superset of Standard. Pick whichever is closest to what you need and treat it as a starting point: after import everything is a normal, editable copy, so retune thresholds, add or drop panels, and adjust queries for your environment — your edits reshape the demand automatically. Start small and re-import a larger variant later if you outgrow it.
The golden signals. 1 dashboard · 4 panels · 3 alerts — backends, connection headroom, transactions, and cache efficiency at a glance.
Import this variant from the catalog. Its demand slug:
postgresql-otel-demand-essentialDashboard — Active backends, Connection utilization, Transaction rate, and Cache hit ratio.
Alerts (3)
| Alert | Severity | Fires when |
|---|---|---|
| PostgreSQL connection saturation | critical | > 90% of max_connections for 5m |
| PostgreSQL low cache hit ratio | warning | hit ratio < 95% for 15m |
| PostgreSQL high rollback ratio | warning | rollbacks > 10% for 10m |
Well-rounded coverage. 1 dashboard · 8 panels · 6 alerts — adds rollbacks, tuple throughput, database size, and dead-row bloat. The recommended default.
Import this variant from the catalog. Its demand slug:
postgresql-otel-demand-standardDashboard — everything in Essential, plus Rollback rate, Tuple operations, Database size, and Live vs dead rows.
Alerts (6)
| Alert | Severity | Fires when |
|---|---|---|
| PostgreSQL connection saturation | critical | > 90% of max_connections for 5m |
| PostgreSQL low cache hit ratio | warning | hit ratio < 95% for 15m |
| PostgreSQL high rollback ratio | warning | rollbacks > 10% for 10m |
| PostgreSQL high dead tuples | warning | > 100k dead tuples for 15m |
| PostgreSQL replication lag (bytes) | critical | replica > 100 MB behind for 5m |
| PostgreSQL high backend count | warning | > 100 backends for 5m |
Deep server visibility. 1 dashboard · 14 panels · 10 alerts — checkpoints, temp files, scan patterns, deadlocks, and replication for servers you need to diagnose, not just watch.
Import this variant from the catalog. Its demand slug:
postgresql-otel-demand-extendedDashboard — everything in Standard, plus Index scans, Checkpoints, Temp files, Sequential scans, Deadlocks, and Replication byte lag.
Alerts (10)
| Alert | Severity | Fires when |
|---|---|---|
| PostgreSQL connection saturation | critical | > 90% of max_connections for 5m |
| PostgreSQL low cache hit ratio | warning | hit ratio < 95% for 15m |
| PostgreSQL high rollback ratio | warning | rollbacks > 10% for 10m |
| PostgreSQL high dead tuples | warning | > 100k dead tuples for 15m |
| PostgreSQL replication lag (bytes) | critical | replica > 100 MB behind for 5m |
| PostgreSQL high backend count | warning | > 100 backends for 5m |
| PostgreSQL recurring deadlocks | warning | recurring deadlocks for 15m (opt-in) |
| PostgreSQL high temp file rate | warning | > 5 temp files/s for 10m (opt-in) |
| PostgreSQL high sequential scan rate | warning | > 100 seq scans/s for 15m (opt-in) |
| PostgreSQL replication replay lag | warning | replay lag > 30s for 5m |
Dashboards
Section titled “Dashboards”Each variant imports one PostgreSQL dashboard, its panels grouped into
collapsible sections. Every dashboard carries an Instance filter (on the
instance label), so one import covers the whole fleet — view every instance
at once, or focus on one. Legends are sortable tables showing last/mean/max per
series, so the outlier instance stands out. Dashboards are demand-driven:
importing one tells your agents to forward exactly the timeseries its panels
query, and nothing else. Panels are ordinary Perses panels — edit queries, add
panels, or retune them after import, and your changes reshape the demand
automatically.
Alerts
Section titled “Alerts”Thresholds are conservative starting points — tune them to your workload.
Next steps
Section titled “Next steps”- Demand-driven observability — why importing a demand also shapes what your agents collect.
- Agent configuration — the full agent config surface.
Thanks for your feedback!
Report sent — thank you!