MakeStack
Back to Feed

Postgres observability with Grafana, Mimir, Loki, Tempo, and Alloy

A Docker Compose observability stack with Grafana, Loki, Mimir, Tempo, Alloy, and PostgreSQL, including the path that makes 362 Postgres metrics available in Grafana through Mimir.

Service versions and responsibilities
ServiceImageRole
grafanagrafana/grafana:13.1web UI and data source provisioning
postgrespostgres:18.4application database and metrics target
lokigrafana/loki:3.7.3log storage
mimirgrafana/mimir:3.1.2metrics storage
alloygrafana/alloy:v1.17.1collector, exporter, and OTLP receiver
tempografana/tempo:3.0.2trace storage

The main metrics path is Postgres -> Alloy -> Mimir -> Grafana.

With the Postgres exporter target scraped by Alloy, this stack reports 362 Postgres metric series. Grafana reads those metrics from Mimir, so Postgres health and activity can be checked from the same UI as logs and traces.

Postgres metrics flow#

Alloy runs several pipelines in one process: Docker container logs go to Loki, OTLP logs and metrics are converted and forwarded, OTLP traces go to Tempo, node metrics are scraped through the Unix exporter, and Postgres metrics are collected through the embedded Postgres exporter.

Examplepromql
count by(__name__) ({job="integrations/postgres"})

Sample Postgres dashboard coverage#

The sample PostgreSQL dashboard is organized by operational questions: is the database reachable, how much traffic is moving through it, whether replication is healthy, how WAL and checkpoints behave, which queries are expensive, whether vacuum keeps up, where locks appear, what the logs say, and how the container uses host resources.

Server Health and Availability

Covers instance up status, primary or replica role, restart detection, exporter scrape errors, and configured database connection limits.

Traffic, Transactions, and Connections

Covers commits versus rollbacks, active backends, connection states, idle-in-transaction sessions, max connections, and longest transaction duration.

Replication Monitoring

Covers replica role, replica lag, WAL replay delay, member availability, replication slot activity, and WAL retained by slots.

WAL and Checkpoints

Covers WAL size, WAL segment count, archive success and failure counts, checkpoint activity, checkpoint duration, and buffers written.

Query Performance

Covers cache hits versus reads, block I/O time, processed rows, pg_stat_statements call count and total time, and sequential versus index scans.

Slow Query Analytics

Covers mean query latency, query calls, total execution time, temporary bytes, and slow-query log entries.

Vacuum and Bloat Monitoring

Covers dead and live tuples, vacuum and analyze counts, time since the last vacuum, and transaction ID age.

Connection and Lock Troubleshooting

Covers locks by mode, deadlocks, blocked sessions, idle-in-transaction sessions, longest transaction duration, and sessions by state.

PostgreSQL Log Analytics

Covers all Postgres logs plus filtered views for errors, warnings, authentication, deadlocks, locks, checkpoints, and autovacuum activity.

System and Container Resource Usage

Covers container CPU, memory, network I/O, disk I/O, database size, and table size.

Logs and traces#

The observability.logs label marks the containers that should be collected by the Docker log pipeline. Alloy reads the Docker socket, keeps only those labeled containers, adds project, service, container, and container_id labels, and forwards their logs to Loki.

For OTLP traffic, Alloy exposes gRPC on 4317 and HTTP on 4318. OTLP logs are converted to Loki, OTLP metrics are converted to Prometheus remote write for Mimir, and OTLP traces are batched and sent to Tempo.

Alloy telemetry routing
SourceDestination
Docker logs with observability.logs=trueLoki
OTLP logs on 4317/4318Loki
OTLP metrics on 4317/4318Mimir
OTLP traces on 4317/4318Tempo
Node exporter metricsMimir
Postgres exporter metricsMimir