pgblame

Setting up pgblame with Neon

A 5-minute walkthrough for Neon serverless Postgres.

1. Enable pg_stat_statements

Neon allows the extension but doesn't install it by default. Connect via Neon's SQL Editor (or any client) as the project owner role and run:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Verify it's loaded:

SELECT extname FROM pg_extension WHERE extname = 'pg_stat_statements';
-- 1 row

2. Create a read-only role for pgblame

Run as the project owner:

-- Create the role
CREATE ROLE pgblame_reader WITH LOGIN PASSWORD '<choose-something-strong>';

-- Read pg_stat_statements (safe: never exposes app data)
GRANT pg_read_all_stats TO pgblame_reader;

-- Allow it to connect
GRANT CONNECT ON DATABASE neondb TO pgblame_reader;

Replace neondb with your actual database name if it differs.

3. Get the connection string

In the Neon console: Connection Details on the project page. Switch the role dropdown to pgblame_reader and copy the Direct connection string (not the pooled one — the agent reconnects rarely and the pooler's session-mode quirks aren't worth it).

postgresql://pgblame_reader:<password>@ep-xxxx.region.aws.neon.tech/neondb?sslmode=require&channel_binding=require

4. Get a project token from pgblame

In your pgblame dashboard:

  • Click New project.
  • Name it (e.g. "myapp-prod").
  • The wizard tests the connection, then issues a one-time token like pgb_xxxxxxxx. Copy it now; it's shown once.

5. Run the agent

docker run -d \
  --name pgblame-agent \
  --restart unless-stopped \
  -e PGBLAME_DATABASE_URL="postgresql://pgblame_reader:...@ep-xxxx.region.aws.neon.tech/neondb?sslmode=require&channel_binding=require" \
  -e PGBLAME_TOKEN="pgb_xxxxxxxx" \
  -v pgblame-data:/var/lib/pgblame \
  ghcr.io/liberzon/pgblame-agent:latest

6. Wire deploy webhooks

Neon-specific notes

  • Compute scale-to-zero: Neon suspends idle compute after a few minutes. The agent's next tick will incur a ~1–3 second cold start as compute resumes; this is harmless. If you want to keep pg_stat_statements warm, disable autosuspend on the branch.
  • Branches: If you point the agent at a branch other than main, regression detection still works, but query-text continuity depends on the branch surviving across deploys. Production should be main.
  • pg_stat_statements lifetime: Neon resets the view on compute restart. The agent stores its own deltas locally, so a reset mid-tick produces one missing data point and recovers on the next.

Troubleshooting

SymptomLikely cause
pg_stat_statements does not existSkipped step 1 — re-run the CREATE EXTENSION statement.
permission denied for view pg_stat_statementsRole missing pg_read_all_stats grant.
SSL connection requiredAppend ?sslmode=require to the connection string.
First tick takes 5+ secondsCompute was suspended; subsequent ticks are millisecond-fast.