Prometheus/VictoriaMetrics configuration
Configuration for the time-series database storing monitoring metrics.
PostgresAI uses VictoriaMetrics by default — a Prometheus-compatible TSDB with better performance and compression.
Authentication and security
New in 0.15, the VictoriaMetrics endpoint is protected with HTTP basic auth. Two .env keys
are now required:
VM_AUTH_USERNAME=vmauth
VM_AUTH_PASSWORD=<non-empty secret>
| Variable | Default | Purpose |
|---|---|---|
VM_AUTH_USERNAME | vmauth | Basic-auth username for the VictoriaMetrics endpoint |
VM_AUTH_PASSWORD | (none — must be set) | Basic-auth password; generate with openssl rand -base64 18 |
What it protects and why it is required:
- It guards the VictoriaMetrics HTTP API so the metrics store is not exposed unauthenticated.
- Grafana's provisioned datasource authenticates with these same credentials. If they are missing or empty, Grafana cannot query VictoriaMetrics and all dashboards show no data.
- The shipped
.env.exampleships empty placeholders that make Docker Compose fail fast until a value is set, to prevent an accidentally unauthenticated deployment.
The CLI (postgresai mon local-install / mon update / mon update-config) generates and
preserves these automatically. If you run Docker Compose directly, you must add them before
docker compose up -d — see
Upgrading the monitoring stack.
Rotating VictoriaMetrics credentials
The monitoring project directory (~/.config/postgresai/monitoring/ for npx/global installs)
contains only docker-compose.yml, instances.yml, .pgwatch-config, and .env — the
scripts/ directory is not copied there. So the simplest path that works for every install
type is to set a new password in .env and then recreate the affected services:
# Edit ~/.config/postgresai/monitoring/.env and set a new VM_AUTH_PASSWORD, e.g.
# VM_AUTH_PASSWORD=$(openssl rand -base64 18)
# then recreate sink-prometheus (to pick up the new -httpAuth password) and Grafana
# (to re-provision its datasource with the new password):
docker compose up -d --force-recreate sink-prometheus grafana
mon update-config does not rotate the passwordRunning postgresai mon update-config alone is not enough here: it migrates required
.env keys (additive), refreshes the CLI-owned docker-compose.yml for non-git installs (a
no-op for git checkouts), and regenerates the pgwatch sources (docker compose run --rm sources-generator). Since 0.17 it also brings a running sink-prometheus in line with .env
(docker compose up -d --no-deps sink-prometheus), but it never restarts Grafana. Grafana provisions its datasource
(with editable: false) only at container startup, so a rotated VM_AUTH_PASSWORD does not take
effect in the running Grafana until it is recreated — which is exactly why the bundled
scripts/rotate-vm-auth.sh runs docker compose up -d --force-recreate sink-prometheus grafana.
If you are working from a full git checkout of the repository, the bundled helper
scripts/rotate-vm-auth.sh does the same thing in one step (run it from the repo root, not from
the monitoring project directory):
VM_AUTH_PASSWORD="$(openssl rand -base64 18)" ./scripts/rotate-vm-auth.sh
After rotating, confirm the recreated services are running:
postgresai mon health
mon health only checks that each container is running (via docker inspect); it does not query
Grafana or VictoriaMetrics, so it will not surface a stale credential on its own. To confirm the
new credentials actually work, open a dashboard in Grafana (it should render data, not an auth
error) or query the VictoriaMetrics API directly with the new basic-auth credentials (the bundled
stack publishes VictoriaMetrics on host port 59090):
curl -fsS -u "${VM_AUTH_USERNAME:-vmauth}:${VM_AUTH_PASSWORD}" \
'http://localhost:59090/api/v1/query?query=up'
A 200 with a JSON result confirms the new credentials are accepted; a 401 means Grafana would
also fail to authenticate.
This rotates the VictoriaMetrics basic-auth credentials. To rotate the monitored database role's password instead, see Rotate monitoring database credentials.
Admin-endpoint keys
Since 0.17, four groups of VictoriaMetrics administrative endpoints (series deletion, snapshots, forced merge, and pprof) require their own key, separate from basic auth. Without these keys, anyone holding read credentials — including a Grafana Viewer, through the datasource proxy — could delete the whole metrics history.
.env variable | VictoriaMetrics flag | Guards |
|---|---|---|
VM_DELETE_AUTH_KEY | -deleteAuthKey | /api/v1/admin/tsdb/delete_series, /tags/delSeries |
VM_SNAPSHOT_AUTH_KEY | -snapshotAuthKey | /snapshot/* |
VM_FORCE_MERGE_AUTH_KEY | -forceMergeAuthKey | /internal/force_merge |
VM_PPROF_AUTH_KEY | -pprofAuthKey | /debug/pprof/* |
postgresai mon local-install,mon update, andmon update-configgenerate any missing or blank key (32 random bytes, hex) and keep existing ones.mon updateandmon update-configthen apply them to a running sink-prometheus withdocker compose up -d --no-deps sink-prometheus.- If you run Docker Compose directly, set them yourself (
openssl rand -hex 32). A blank key never leaves an endpoint open: sink-prometheus generates a random one at every start, which you cannot use. - The keys, and the basic-auth password, are passed to VictoriaMetrics as
file://paths, so they do not appear in its command line or in/debug/pprof/cmdline. They are still container environment variables, visible to anyone with access to the Docker socket (docker inspect). - No metrics reader (Grafana, the Flask backend, the reporter) receives these keys.
- Other VictoriaMetrics endpoints still accept basic auth alone, including maintenance ones such as
/internal/resetRollupResultCacheand/-/reload. Grafana access is still access to the metrics store: grant it only to people you would trust with the metrics.
To call an admin endpoint, pass the key as the authKey query argument. A key replaces basic auth
for its endpoints, so treat each one as a separate secret. Pipe it to curl rather than putting it on
the command line, where other users of the host can see it in the process list:
# From the monitoring directory: read the key from .env, then list snapshots
sed -n 's/^VM_SNAPSHOT_AUTH_KEY=//p' .env | tr -d '\n' |
curl -sG --data-urlencode authKey@- http://localhost:59090/snapshot/list
tr -d '\n' matters: curl would otherwise send the trailing newline as part of the key, and
VictoriaMetrics answers The provided authKey doesn't match -snapshotAuthKey.
To rotate a key, set a new value in .env and recreate sink-prometheus:
docker compose up -d --no-deps sink-prometheus
Admin-endpoint keys are set by the Docker Compose stack and the Terraform AWS deployment. The Helm
chart does not set them, and its VictoriaMetrics basic auth is off by default
(victoriaMetrics.auth.enabled: false), so out of the box anyone who can reach VictoriaMetrics or
use Grafana can call the admin endpoints. Add the keys through victoriaMetrics.extraArgs, restrict
access to the VictoriaMetrics service with a NetworkPolicy, and limit who can use Grafana. See
VictoriaMetrics admin endpoints.
Retention
Setting retention period
# Set in the monitoring stack .env file.
# Default is 336h (14 days); the value below overrides it to 30 days.
VM_RETENTION_PERIOD=30d
# Migrate .env. Since 0.17, `mon update-config` also applies it to a running
# sink-prometheus; on older CLIs, recreate sink-prometheus yourself (next line).
postgresai mon update-config
docker compose up -d --force-recreate sink-prometheus
| Retention | Disk usage (approx) | Use case |
|---|---|---|
| 7d | ~500 MiB per database | Development |
| 14d | ~1 GiB per database | Default |
| 30d | ~2 GiB per database | Production |
| 90d | ~6 GiB per database | Compliance requirements |
| 9490h | ~26 GiB per database | Long history (13 months) |