Architecture¶
PgPulse is split into an in-database collector and an external exporter.
That split is important. The PostgreSQL extension can see PostgreSQL internals cheaply. The exporter can speak normal HTTP and Prometheus without running inside the database process.
Main Components¶
PostgreSQL Extension¶
Location:
pgpulse/
The extension is a cdylib built with pgrx.
When PostgreSQL starts with shared_preload_libraries = 'pgpulse', PostgreSQL loads the extension library and calls _PG_init().
Inside _PG_init(), PgPulse:
- Registers its PostgreSQL settings.
- Initializes shared memory.
- Registers a background worker, but only from the postmaster process.
The background worker is named:
postgres monitoring worker
Background Worker¶
Location:
pgpulse/src/bgw.rs
The worker wakes up every pgpulse.poll_interval_seconds. The default is 10 seconds.
Each cycle does this:
- Reads replication clients from
pg_stat_replication. - Reads long-running queries from
pg_stat_activity. - Optionally connects to the replica with raw
libpq. - Calculates the health status.
- Writes the latest snapshot to PostgreSQL shared memory.
The worker uses SPI for queries against the primary. It uses raw libpq for the replica connection because normal Rust PostgreSQL clients are not a good fit inside a PostgreSQL background worker.
Shared Memory¶
Location:
pgpulse/src/shared_mem.rs
PgPulse stores only the latest snapshot.
That keeps the extension simple:
- One writer: the background worker
- Many readers: SQL functions and views
- No history table
- No write load on user databases
The shared memory value is protected by a PostgreSQL lightweight lock.
SQL Surface¶
Location:
pgpulse/sql/pgpulse--0.2.0.sql
The Rust functions are exposed through simple SQL views and functions.
User-friendly SQL objects:
SELECT * FROM pgpulse.replication_status;
SELECT * FROM pgpulse.long_running_queries;
SELECT pgpulse_health_status();
SELECT pgpulse_collected_at();
The SQL install file grants public read access to the monitoring views and functions.
Exporter¶
Location:
pgpulse-exporter/
The exporter is a Rust binary using:
axumfor HTTPtokio-postgresfor PostgreSQL accessprometheusfor metric registration and text encodingserde_yamlfor config loadingclapfor CLI parsing
The exporter connects to the primary database and reads the extension output.
It serves:
GET /healthGET /replication-statusGET /metrics
Data Flow¶
Replica
provides replay timestamp
^
|
Primary PostgreSQL
pgpulse background worker
pg_stat_replication
pg_stat_activity
shared memory snapshot
^
|
pgpulse SQL views and functions
^
|
pgpulse-exporter
^
|
Prometheus
^
|
Grafana
Health Logic¶
Location:
pgpulse/src/health/evaluator.rs
Health is based on:
- Whether replication clients exist
- LSN gap thresholds
- Replica replay lag thresholds
Default behavior:
- No replication clients means
Warning - LSN gap at or above
pgpulse.lsn_gap_warning_bytesmeansWarning - LSN gap at or above
pgpulse.lsn_gap_critical_bytesmeansCritical - Replica replay lag at or above
pgpulse.replay_lag_warning_secondsmeansWarning - Replica replay lag at or above
pgpulse.replay_lag_critical_secondsmeansCritical
The exporter maps health to numbers for Prometheus:
0 = Healthy
1 = Warning
2 = Critical