pgblame

Running the pgblame agent

The agent is one small (~25 MB) container. It samples pg_stat_statements about once a minute, computes per-query deltas, and POSTs them to pgblame. It is outbound-only — it opens no ports, and it connects out to your Postgres and to pgblame.

Because it's outbound-only, it does not need to run inside your database's cloud. Supabase and Neon users: the agent runs anywhere with an outbound network — your laptop, a tiny worker, your own cluster — and reaches your database over its normal connection string. Run one agent per database.

Prefer to hand this to your AI agent?

Copy a setup prompt and paste it into Claude, Cursor, or ChatGPT — it walks through the database role and the agent install for you. You provide your own database connection string.

Fastest way — Docker

docker run -d \
  --name pgblame-agent \
  --restart unless-stopped \
  -e PGBLAME_DATABASE_URL='postgresql://...' \
  -e PGBLAME_TOKEN='pgb_...' \
  -v pgblame-data:/home/nonroot/.pgblame \
  ghcr.io/liberzon/pgblame-agent:latest

The agent ships its first delta after two ticks (~2 minutes). The -v mount persists the buffer at the default PGBLAME_DATA_DIR (see The local buffer) and is optional — drop it and the agent runs on its in-container buffer, re-baselining on restart.

Where to run it

It just needs an always-on process with outbound network. Pick whatever you already have:

  • Your laptop — perfect for trying it out; run the Docker command above.
  • A cheap always-on worker — Fly.io (free allowance), Railway, Koyeb, or a Render background worker (not a free web service — those sleep). Deploy the image, set the two env vars.
  • Docker Compose — one file on any box.
  • Kubernetes — Helm or a plain manifest; works on EKS, GKE, AKS, k3s, anything.
  • AWS ECS — a Fargate task.

Environment variables

VariableRequiredDefaultNotes
PGBLAME_DATABASE_URLyesConnection string for the Postgres you want to monitor.
PGBLAME_TOKENto shipProject token from the dashboard. Omit to dry-run locally (buffers, doesn't POST).
PGBLAME_DASHBOARD_URLnohttps://pgblame.comWhere snapshots are sent.
PGBLAME_DATA_DIRno/home/nonroot/.pgblameSQLite buffer location. Mount a volume here to persist it across restarts.
PGBLAME_SAMPLE_INTERVAL_SECONDSno60Sample interval; 30–600.

No CLI flags — everything is configured through env vars.

The local buffer

The agent keeps a tiny SQLite buffer at PGBLAME_DATA_DIR: the previous tick's counters (to compute deltas) and a durable retry queue for snapshots that haven't shipped yet. Persisting it (a Docker volume, a k8s PVC, an ECS EFS mount) is recommended but not required. Without a persistent volume the agent still works — on a restart you simply lose one delta window and any un-shipped payloads, then it re-baselines and carries on.

Run a single agent per database. Two agents racing on the same pg_stat_statements double-count deltas, so keep replicas at 1.

Serverless functions

Running the agent as a serverless function (Vercel / Firebase / Supabase / Neon functions) isn't supported yet. The agent is a resident poller that keeps a local buffer between ticks; a stateless, per-request function runtime can't hold that state. A native serverless mode (single-tick + server-side baselines, driven by your platform's scheduler) is on the roadmap.

In the meantime you don't need to manage a server: run the ~25 MB container on a free/cheap always-on worker (see Where to run it) — it connects out to your Supabase/Neon database just fine. Want the serverless beta, or running somewhere not listed here? Email hi@pgblame.com with your platform — it helps us prioritize.

Tell pgblame about deploys

Correlation needs deploy events. Wire one:

Running the agent — pgblame