Getting Started
Categories:
This page is the shortest path: install pg_exporter, connect it to a PostgreSQL instance, verify metrics output, and hook it into Prometheus.
You only need two things: a reachable PostgreSQL 10-19+ (or pgBouncer 1.8+) instance, and permission to create a user in it. For older PostgreSQL 9.1-9.6 instances, see Compatibility.
Step 1: Install
On Linux amd64 you can download the binary directly (for other platforms and RPM/DEB/Docker options, see the Installation guide):
VERSION=$(curl -fsSL https://api.github.com/repos/pgsty/pg_exporter/releases/latest | sed -n 's/.*"tag_name": "v\([^"]*\)".*/\1/p')
wget "https://github.com/pgsty/pg_exporter/releases/download/v${VERSION}/pg_exporter-${VERSION}.linux-amd64.tar.gz"
mkdir -p "pg_exporter-${VERSION}.linux-amd64"
tar -xf "pg_exporter-${VERSION}.linux-amd64.tar.gz" -C "pg_exporter-${VERSION}.linux-amd64"
sudo install "pg_exporter-${VERSION}.linux-amd64/pg_exporter" /usr/bin/
sudo install "pg_exporter-${VERSION}.linux-amd64/pg_exporter.yml" /etc/pg_exporter.yml
Confirm the installation:
pg_exporter --version
# pg_exporter v1.4.1 (built with go1.26.5 on linux/amd64)
Step 2: Create a Monitoring User
Create a dedicated monitoring user on the target PostgreSQL. The built-in pg_monitor role (PostgreSQL 10+) covers all read permissions the default collectors need:
CREATE USER monitor WITH PASSWORD 'S3cret';
GRANT pg_monitor TO monitor;
If you are just trying it out locally as a superuser like postgres, you can skip this step.
Step 3: Run and Verify
Use --dry-run to confirm the configuration parses, then start for real:
export PG_EXPORTER_URL='postgres://monitor:S3cret@localhost:5432/postgres'
pg_exporter --dry-run # print parsed collector config, then exit
pg_exporter # start for real, listening on :9630 by default
Without any URL, pg_exporter falls back to the local-first default postgresql:///?sslmode=disable, which fits running on the same host as PostgreSQL. The full URL source precedence (--url > PG_EXPORTER_URL > PGURL > PG_EXPORTER_URL_FILE > default) is documented in the Deployment guide.
Pull the metrics from another terminal:
curl -s http://localhost:9630/metrics | grep -E '^pg_(up|version|in_recovery) '
You should see the three core built-in metrics:
pg_up 1 # 1 when the target is reachable, 0 otherwise
pg_version 170000 # version in server_version_num format
pg_in_recovery 0 # 1 on replicas, 0 on primaries
pg_up 1 means the pipeline works — the remaining 600+ metrics (pg_db_*, pg_table_*, pg_wal_*, …) all come from the declarative collector definitions in pg_exporter.yml. If pg_up is 0, restart with pg_exporter --log.level=debug and inspect the connection error.
Step 4: Hook into Prometheus
Add a scrape target in prometheus.yml:
scrape_configs:
- job_name: 'postgresql'
scrape_interval: 15s
static_configs:
- targets: ['localhost:9630']
Collectors cache results per their ttl (most realtime collectors use ttl: 10): as long as the TTL is below the scrape interval, every scrape gets fresh data, while high-frequency scraping can never overwhelm the database. This is also why setting scrape_interval below the common TTLs is not recommended.
That’s it. For Grafana, you can reuse the PostgreSQL dashboards from Pigsty, or explore the live demo.
Troubleshooting
| Symptom | What to do |
|---|---|
pg_up 0, connection fails |
Run pg_exporter --log.level=debug and read the error; check URL, pg_hba.conf, and network reachability |
| Some metrics are missing | curl localhost:9630/explain to see each collector’s planning verdict (version gates, tags, predicates) |
| A collector keeps failing | curl localhost:9630/stat for per-collector error counters and durations |
| Scrapes are slow | Find the slow collector in /stat, raise its ttl, or set skip: true |
/stat, /explain, and /reload are management endpoints — protect them with --web.config.file (TLS/auth) or keep them on a trusted network in production. See the API Reference.
Next Steps
- Monitor pgBouncer, enable auto-discovery, deploy with systemd / Docker / Kubernetes: Deployment guide
- Understand and customize collectors (GAUGE/COUNTER/HISTOGRAM, TTL, tags, version gates): Configuration reference
- Health check and primary/replica traffic routing endpoints (
/up,/primary,/replica): API Reference