Skip to main content
View rawEdit

Configuration

Configuration guides for customizing PostgresAI monitoring components.

Components​

ComponentPurposeConfiguration scope
pgwatchMetrics collectionCollection intervals, custom metrics
VictoriaMetricsTime-series storageRetention, storage, scrape settings
GrafanaVisualizationDashboards, data sources, authentication
AlertingNotificationsAlert rules, notification channels

Configuration methods​

CLI installation​

Configuration is stored in the monitoring directory .env file. update-config migrates .env and regenerates the pgwatch sources.yml, but it does not restart services — keys read by a service at container startup (e.g. the VM_* flags below, consumed by sink-prometheus) only take effect once that service is recreated:

# Example .env overrides (default VM_RETENTION_PERIOD is 336h ≡ 14 days)
VM_RETENTION_PERIOD=30d
VM_QUERY_DURATION=30s
VM_MAX_CONCURRENT_REQUESTS=16

postgresai mon update-config
# These VM_* values are read by sink-prometheus at startup; recreate it to apply:
docker compose up -d --force-recreate sink-prometheus

Docker Compose​

Configuration is passed through docker-compose.yml and the generated .env file:

# Example overrides (default VM_RETENTION_PERIOD is 336h ≡ 14 days)
VM_RETENTION_PERIOD=30d
VM_QUERY_DURATION=30s
VM_MAX_CONCURRENT_REQUESTS=16

Helm​

Configuration via values.yaml (see Helm installation):

victoriaMetrics:
retentionPeriod: 336h # default; 14 days
scrapeInterval: 15s

Quick reference​

SettingDefaultDescription
Scrape interval15sHow often to collect metrics (victoriaMetrics.scrapeInterval)
Retention14 days (336h)How long to keep metrics (VM_RETENTION_PERIOD / victoriaMetrics.retentionPeriod)
Query-id mapping retention720 hours (30 days)How long the Flask backend keeps the queryid → query-text mapping (QUERYID_RETENTION_HOURS, a bare integer number of hours — no h suffix)

Resource limits (per service)​

New in 0.15, each monitoring-stack service has optional CPU and memory limits exposed as .env variables. All of them are optional — leaving them unset preserves the default laptop/dev sizing and produces no behavior change. Memory limits are in bytes (Docker Compose mem_limit convention); *_CPUS values are floats (Docker Compose cpus: semantics). Provisioning playbooks can export production-grade values per VM size class without forking the compose file.

ServiceCPU variableMemory variableDefault memory
Demo target databaseTARGET_DB_CPUS (0.2)TARGET_DB_MEM768 MiB
Demo target standbyTARGET_STANDBY_CPUS (0.2)TARGET_STANDBY_MEM768 MiB
Postgres sinkSINK_POSTGRES_CPUS (0.4)SINK_POSTGRES_MEM1 GiB
VictoriaMetrics sinkSINK_PROMETHEUS_CPUS (0.75)SINK_PROMETHEUS_MEM1.5 GiB
pgwatch (Postgres sink)PGWATCH_POSTGRES_CPUS (0.35)PGWATCH_POSTGRES_MEM512 MiB
pgwatch (Prometheus sink)PGWATCH_PROMETHEUS_CPUS (0.5)PGWATCH_PROMETHEUS_MEM512 MiB
GrafanaGRAFANA_CPUS (0.5)GRAFANA_MEM512 MiB
Flask backendFLASK_CPUS (0.5)FLASK_MEM1 GiB
ReporterPOSTGRES_REPORTS_CPUS (1.0)POSTGRES_REPORTS_MEM1.75 GiB
cAdvisor (self-monitoring)CADVISOR_CPUS (0.25)CADVISOR_MEM384 MiB
node exporter (self-monitoring)NODE_EXPORTER_CPUS (0.05)NODE_EXPORTER_MEM96 MiB
postgres exporter (self-monitoring)POSTGRES_EXPORTER_CPUS (0.1)POSTGRES_EXPORTER_MEM128 MiB

Set the values in the monitoring stack .env. These are Compose cpus: / mem_limit: keys that only take effect when a container is recreated, so after migrating .env with postgresai mon update-config recreate the affected services with docker compose up -d --force-recreate <service> (or set the values before the initial docker compose up -d for manual installs); update-config does not recreate services. The VictoriaMetrics engine tuning flags (VM_QUERY_DURATION, VM_MAX_CONCURRENT_REQUESTS) are documented under Query and search tuning.

Config seeding and operator edits​

The stack seeds its generated configuration once and guards it with a version marker, so operator edits to provisioned config persist across restarts and are not silently overwritten. The reseed is performed by the config-init service: on start it compares the image's /VERSION against the .pgai-configs-version marker in the config volume, and reseeds only when they differ. A reseed therefore happens when you recreate the stack on a newer image — i.e. on docker compose up -d after the image tag (and thus the image version) is bumped, since up -d recreates config-init from the new image and it then sees the version mismatch. (postgresai mon start runs docker compose up -d only when the stack is stopped — on an already-running stack it reports Monitoring services are already running and exits without recreating anything — so for an in-place upgrade of a running stack, run docker compose up -d directly to recreate config-init, not mon start.) postgresai mon restart does not trigger a reseed: it runs docker compose restart, which restarts the existing config-init container in place on the old image, so it still reads the old /VERSION, the marker still matches, and nothing is re-copied. Note that postgresai mon update-config does not reseed the volume either: it migrates the .env file (additive required keys), refreshes the CLI-owned docker-compose.yml to match the stack version for non-git/global installs (a no-op for git checkouts; it touches only the compose file, never .env/instances.yml/.pgwatch-config), and regenerates the pgwatch sources (docker compose run --rm sources-generator). It does not restart Grafana or sink-prometheus. To force a fresh reseed, remove the version marker from the config volume so config-init re-copies the image defaults on the next start.

The config-init service is the only one that mounts the volume read-write (at /target); every long-running service mounts it read-only (/postgres_ai_configs:ro), so you cannot delete the marker from, say, the Grafana container. The service is also a one-shot init container that exits immediately, so plain docker exec config-init … fails (the container name is postgres-ai-config-init and it is not running). Instead, run a throwaway config-init with its entrypoint overridden to rm (its normal entrypoint is the seeder script, which ignores extra arguments), then restart:

docker compose run --rm --entrypoint rm config-init /target/.pgai-configs-version
docker compose up -d --force-recreate config-init

docker compose up -d --force-recreate config-init recreates the one-shot config-init container; with the marker now absent, init-configs.sh reseeds unconditionally. (A plain docker compose up -d also works — it recreates config-init because nothing else depends on the cleared marker — but the explicit --force-recreate config-init makes the intent unambiguous.) Do not use postgresai mon start here: on an already-running stack mon start only checks whether the containers are up and, if they are, prints Monitoring services are already running and exits without running docker compose up -d, so config-init is never recreated and the reseed silently does not happen. Likewise postgresai mon restart only restarts the existing containers in place and would not re-run the seeder against the cleared volume. Recreating config-init on a live stack must therefore go through docker compose up -d directly.

Sections​