Configuration
Each business metric in pg_exporter comes from a YAML collector definition.
A collector contains one SQL query and its execution conditions: version, role, tags, and predicates.
It also controls caching and timeout. This page describes all collector settings.
Use one YAML file, such as the default pg_exporter.yml, or a directory of YAML files.
The official default bundle combines 58 definition files from config/.
Configuration Loading
PG Exporter searches for configuration in the following order:
- Command-line argument:
--config=/path/to/config - Environment variable:
PG_EXPORTER_CONFIG=/path/to/config - Current directory:
./pg_exporter.yml - System config file:
/etc/pg_exporter.yml - System config directory:
/etc/pg_exporter/
Directory mode details:
- The exporter loads only
.yml/.yamlfiles in the specified directory. It does not read subdirectories. - It merges files in lexicographic order. A later file overrides an earlier collector definition with the same top-level name.
- If the directory contains YAML files but none can be parsed, the exporter returns an error.
Collector Structure
Define each collector as a top-level YAML object with a unique name and the required properties:
Validation rules:
- Each entry in
metricsmust define exactly one column mapping. - Each collector must expose at least one
GAUGE,COUNTER, orHISTOGRAMcolumn. usageaccepts onlyGAUGE,COUNTER,HISTOGRAM,LABEL, orDISCARD.- A
HISTOGRAMcolumn must definebucketwith finite upper bounds in strictly increasing order. The exporter appends the+Infbucket. - Metric and label names must follow Prometheus naming rules. The exporter checks them during loading and rejects invalid configurations immediately.
- Constant labels cannot conflict with query labels or built-in dynamic labels such as
datnameandquery. The exporter checks this during loading. If any collector usesHISTOGRAM,leis reserved and cannot be a constant label. - The SQL result must include every
LABELcolumn. Fromv1.4.1, a missing label column fails the entire collector scrape. The collector does not emit an empty label or keep stale results. Other non-fatal collectors continue. - In one-line inline
metricsdefinitions, enclosedescriptionvalues in double quotes to prevent YAML ambiguity.
Core Configuration Elements
Collector Branch Name
The top-level key uniquely identifies a collector across the entire configuration:
Query Definition
The SQL query that retrieves metrics:
Metric Types
Each column in the query result must be mapped to a metric type:
| Usage | Description | Example |
|---|---|---|
GAUGE | Instantaneous value that can go up or down | Current connections |
COUNTER | Cumulative value that only increases | Total transactions |
HISTOGRAM | Snapshot histogram deriving _bucket / _count / _sum series | Transaction age distribution |
LABEL | Use as a Prometheus label | Database name |
DISCARD | Ignore this column | Internal values |
Histogram Columns (HISTOGRAM)
Version v1.4.0 adds the HISTOGRAM column type.
Each query result row is one observation. The exporter groups observations by label to produce a classic Prometheus histogram snapshot.
It generates three series families: <name>_bucket, <name>_count, and <name>_sum.
The bucket series includes the le label and the +Inf bucket:
Usage notes:
- This is a snapshot histogram. Each scrape rebuilds the full distribution. Bucket counts can increase or decrease, as gauges do. Use
histogram_quantile()directly. Do not userate()/increase()on_count/_sum; these operations have no meaning for a snapshot. - By default, the exporter ignores SQL
NULLobservations. If you setdefault, it counts them with that value. - The exporter applies
scalebefore it assigns a bucket. As with scalar columns,scaledoes not apply to timestamps or booleans. - For a reference implementation, see the default
pg_xact_agecollector.
Cache Control (TTL)
The ttl parameter controls result caching:
Best practices:
- Set TTL less than your scrape interval
- Use longer TTL for expensive queries
- TTL of 0 disables caching
Timeout Control
Prevent queries from running too long:
Version Compatibility
Control which PostgreSQL versions can run this collector:
Version numbers follow PostgreSQL server_version_num rules:
100000= 10.0130200= 13.2160100= 16.1190000= 19.090600= 9.6, relevant when using the legacy config bundle
Execution Model
Use the execution model to find why a metric is missing:
- Planning runs when the connection starts or configuration reloads. It checks each branch’s target type (PostgreSQL / pgBouncer),
min_version/max_version,tags, andskipsetting. Tags must match the server role and exporter tags. A branch that fails any check is not installed on the target. Usecurl localhost:9630/explainto see each decision. - Scraping runs on each
/metricsrequest. An installed collector returns cached results while they are withinttl. Otherwise, it first runspredicate_queries. A false result skips the collector for this round and incrementspg_exporter_query_scrape_predicate_skip_count. If all predicates pass, the main query runs withtimeout. The exporter converts the results to metrics and caches them. - Failure semantics: a normal collector failure affects only that collector. It increments
pg_exporter_query_scrape_error_countand omits its metric group for this round. A failed collector withfatal: truefails the entire server scrape.
Tag System
Tags control when and where collectors execute:
Built-in Tags
| Tag | Description |
|---|---|
cluster | Execute once per PostgreSQL cluster |
primary / master | Only on primary servers |
standby / replica | Only on replica servers |
pgbouncer | Only for pgBouncer connections |
Prefixed Tags
| Prefix | Example | Description |
|---|---|---|
dbname: | dbname:postgres | Only on specific database |
username: | username:monitor | Only with specific user |
extension: | extension:pg_stat_statements | Only if extension installed |
schema: | schema:public | Only if schema exists |
not: | not:slow | NOT when exporter has tag |
Custom Tags
Pass custom tags to the exporter:
Then use the tags in the configuration:
Predicate Queries
Run conditional checks before the main query:
The main query only executes if all predicates return true.
Metric Definition
Basic Definition
Advanced Options
Collector Organization
PG Exporter ships with pre-organized collectors:
| Range | Category | Description |
|---|---|---|
| 0xx | Documentation | Examples and documentation |
| 1xx | Basic | Server info, settings, metadata |
| 2xx | Replication | Replication, slots, receivers |
| 3xx | Persistence | I/O, checkpoints, WAL |
| 4xx | Activity | Connections, locks, queries |
| 5xx | Progress | Vacuum, index creation progress |
| 6xx | Database | Per-database statistics |
| 7xx | Objects | Tables, indexes, functions |
| 8xx | Optional | Expensive/optional metrics |
| 9xx | pgBouncer | Connection pooler metrics |
| 10xx+ | Extensions | Extension-specific metrics |
Real-World Examples
Simple Gauge Collector
Counter with Labels
Version-Specific Collector
Extension-Dependent Collector
Custom Collectors
Creating Your Own Metrics
- Create a new YAML file in your config directory:
- Test your collector:
Conditional Metrics
Use predicate queries for conditional metrics:
Performance Optimization
Query Optimization Tips
Use appropriate TTL values:
- Fast queries: 1-10 seconds
- Medium queries: 10-60 seconds
- Expensive queries: 300-3600 seconds
Set realistic timeouts:
- Default: 100ms
- Complex queries: 500ms-1s
- Never disable timeout in production
Use cluster-level tags:
Disable expensive collectors:
Monitoring Collector Performance
Check collector execution statistics:
Troubleshooting Configuration
Validate Configuration
Common Issues
| Problem | Solution |
|---|---|
| Metrics missing | Check tags and version compatibility |
| Slow scrapes | Increase TTL, add timeout, disable expensive queries |
| High memory usage | Reduce result set size, use LIMIT |
| Permission errors | Verify query permissions for monitoring user |
Debug Logging
Enable debug logging to troubleshoot:
Was this page helpful?
Thanks—your feedback helps us improve this page.
What got in the way? (optional)