Skip to content

Getting Started

Prerequisites and the fastest path to a running pg-regression-radar, in any of its three supported forms.

Overview

pg-regression-radar ships two runnable entrypoints (operator and manager) plus a Helm chart that wraps both. This page assumes you already have the binaries, the container image, or a clone of the repo — see Installation if you don't yet. It covers the minimal command to get each form running; see Architecture Overview for which one to pick, and Configuration Reference for every flag and CRD field used below.

The commands below use go run ./cmd/operator/go run ./cmd/manager, which assume a clone of the repo. If you installed the unified CLI instead (see Installation, option 1), replace go run ./cmd/operator with pg-regression-radar operator and go run ./cmd/manager with pg-regression-radar manager — every flag below is identical either way.

If your goal is to prove end-to-end behavior (regression detection + deployment attribution) instead of only bringing services up, follow Quickstart Validation and Example regression scenario after startup.

Prerequisites

  • Go 1.22+ (only needed to build from source; the Dockerfile needs no local Go install)
  • A Postgres cluster with pg_stat_statements enabled — see Support Matrix for officially supported versions/distributions
  • A least-privilege Postgres role for --dsn — see the Creating a least-privilege Postgres role section in the Installation guide. Never use a superuser or application-owner DSN.
  • (Optional) ArgoCD, Argo Rollouts, or Flux for real deploy-event webhooks — see Deploy Sources & Webhooks

Run the all-in-one operator

go run ./cmd/operator \
  --dsn "postgres://user:pass@localhost:5432/mydb?sslmode=disable" \
  --cluster-name my-cluster \
  --namespace production \
  --webhook-listen :8080 \
  --metrics-listen :9090 \
  --slack-url https://hooks.slack.com/services/XXX/YYY/ZZZ \
  --source-type argocd \
  --window-minutes 30 \
  --min-executions 10 \
  --latency-threshold 0.20

Note: The --dsn value above is a placeholder. Replace it with a full PostgreSQL connection URI in the form postgres://username:password@host:port/dbname?sslmode=disable. Redacted DSN examples are shown for documentation safety only and cannot be used as-is.

Run the manager (CRD-driven, HA)

# 1. Install the CRDs (also done automatically by the Helm chart below).
kubectl apply -f config/crd/bases/

# 2. Create a Secret holding the DSN, a PostgresWatch, and a DeploySource.
kubectl create secret generic my-cluster-dsn \
  --from-literal=dsn="postgres://user:pass@cnpg-cluster-rw.production:5432/mydb?sslmode=disable"

cat <<'EOF' | kubectl apply -f -
apiVersion: radar.pgregressionradar.io/v1alpha1
kind: PostgresWatch
metadata:
  name: my-cluster
  namespace: production
spec:
  clusterName: cnpg-cluster
  dsnSecretRef:
    name: my-cluster-dsn
    key: dsn
  windowMinutes: 30
  minExecutions: 10
  latencyChangeThreshold: "0.20"
  slackWebhookUrl: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
---
apiVersion: radar.pgregressionradar.io/v1alpha1
kind: DeploySource
metadata:
  name: my-cluster-argocd
  namespace: production
spec:
  postgresWatchRef: my-cluster
  sourceType: argocd
EOF

# 3. Run the manager (in-cluster it reads a ServiceAccount token
#    automatically; --kubeconfig is only for out-of-cluster/local runs).
go run ./cmd/manager \
  --leader-elect=true \
  --leader-election-namespace=production \
  --webhook-bind-address=:8080 \
  --pg-metrics-bind-address=:9090

# 4. Watch it come up and, later, watch regressions land as CRs.
kubectl get postgreswatch,deploysource -n production
kubectl get performanceregressions -A

Note: The --from-literal=dsn value above is a placeholder. Replace it with a full PostgreSQL connection URI in the form postgres://username:password@host:port/dbname?sslmode=disable. Redacted DSN examples are shown for documentation safety only and cannot be used as-is.

Deploy on Kubernetes via Helm

helm install pg-regression-radar ./deploy/helm/deploylens \
  --set postgres.dsn="postgres://user:pass@cnpg-cluster-rw.production:5432/mydb?sslmode=disable" \
  --set postgres.clusterName=cnpg-cluster \
  --set postgres.namespace=production \
  --set alerting.slackWebhookUrl=https://hooks.slack.com/services/XXX/YYY/ZZZ

The chart's mode value picks the entrypoint (operator, the default above, or manager). In manager mode it also installs the CRDs (deploy/helm/deploylens/crds/), the RBAC the manager needs, and — unless manager.createDefaultWatch=false — a PostgresWatch + DeploySource pair from the same postgres.*/analysis.*/alerting.* values:

helm install pg-regression-radar ./deploy/helm/deploylens \
  --set mode=manager \
  --set manager.replicaCount=2 \
  --set postgres.dsn="postgres://user:pass@cnpg-cluster-rw.production:5432/mydb?sslmode=disable" \
  --set postgres.clusterName=cnpg-cluster \
  --set alerting.slackWebhookUrl=https://hooks.slack.com/services/XXX/YYY/ZZZ

Note: The postgres.dsn values above are placeholders. Replace them with a full PostgreSQL connection URI in the form postgres://username:password@host:port/dbname?sslmode=disable. Redacted DSN examples are shown for documentation safety only and cannot be used as-is.

For hardened alert egress in Helm, set alerting.destinationPolicy (allowlist or relay-only) and the matching companion values (alerting.allowedDestinations and/or alerting.destinationPolicyRelayUrl) — see Alerting: destination policies.

Note

Helm only installs a chart's crds/ directory on helm install, never on helm upgrade — this is a deliberate Helm safety behaviour, not a bug in this chart (see the Helm docs on CRDs). To pick up CRD schema changes after upgrading the chart, apply deploy/helm/deploylens/crds/*.yaml (or config/crd/bases/*.yaml, the same files) with kubectl apply -f directly.

Simulate a deploy event (for testing)

curl -X POST http://localhost:8080/webhook \
  -H "Content-Type: application/json" \
  -d '{
    "app": "my-app",
    "namespace": "production",
    "revision": "abc123def456",
    "imageTag": "my-app:v42",
    "timestamp": "2026-08-11T12:00:00Z"
  }'

That payload matches the generic source type (the default), which accepts a DeployEvent shape directly — see API Reference.

What "detecting a regression" looks like

In practice, successful detection means more than "the process stayed running." You should eventually observe:

  • a specific query identified as regressed,
  • measurable before/after latency change,
  • deploy metadata (app/namespace/revision/image) attached to the same finding.

Depending on mode and configuration, this appears in logs, in PerformanceRegression resources (manager mode), and/or in alert destinations (for example Slack). For a reproducible validation flow with expected outcomes, follow Quickstart Validation.

Troubleshooting common setup issues

  • No deploy events are being ingested: verify your webhook URL/path (/webhook), source type, and authentication header if --webhook-secret is enabled.
  • No regression detected yet: increase traffic volume for the target query, verify pg_stat_statements is enabled, and check detection thresholds (windowMinutes, minExecutions, latency threshold).
  • Manager exits with address already in use on startup: the health probe endpoint listens on :8081 by default (--health-probe-bind-address). If that port is already taken (for example by another manager instance), set a free port, for example --health-probe-bind-address=:18081.
  • Manager mode does not produce resources: confirm CRDs are installed and check namespace-scoped PostgresWatch/DeploySource reconciliation status.
  • Helm manager mode seems missing CRDs on upgrade: Helm installs crds/ only on initial install; apply updated CRDs manually as noted above.
  • Alerts not delivered: validate webhook destination config and any egress/destination policy restrictions.

See also