← Blog3 min read

Safe Migrations for Agents and Humans

A single line of DDL can take down a production database. ALTER TABLE ... ADD COLUMN ... NOT NULL without a default rewrites the whole table. Adding a constraint takes an ACCESS EXCLUSIVE lock that blocks every read and write while it runs. Creating an index without CONCURRENTLY locks writes for the duration. None of these throws an error. They just lock or rewrite, and your application stalls.

Experienced engineers know the list of dangerous patterns and avoid them. Agents do not, and even experienced engineers forget under pressure. PgBeam lints the migration before it runs, so the knowledge lives in the proxy instead of in someone's head.

What it catches

When a credential submits DDL, PgBeam analyzes the statement and flags the patterns that cause outages:

  • Table rewrites: a column add, type change, or alteration that forces Postgres to rewrite every row.
  • ACCESS EXCLUSIVE locks: operations that block all access to a table while they run, on a table that may be hot.
  • Missing CONCURRENTLY: index creation or drops that lock writes when a concurrent variant exists and should have been used.
  • Unsafe column drops and type changes: changes that break a running application reading the old shape, or that are irreversible.
  • NOT NULL without a default: the classic full-table rewrite that looks harmless in a diff.

For each, PgBeam can warn or block, depending on how you configure the credential. The response includes a preview of what the statement would do and a fix hint: the safe rewrite of the migration, like splitting an unsafe column add into an add-nullable, backfill, and set-not-null sequence, or adding CONCURRENTLY to the index build.

The agent angle

A coding agent that writes migrations is enormously useful and exactly the kind of thing you cannot fully trust. The agent knows SQL. It does not necessarily know that the ALTER it just generated will lock your busiest table at peak traffic. The lint is the senior DBA review the agent never had, applied automatically to every migration it produces.

It also closes the loop the way agents work best. The block comes back as a readable error with the fix hint, so the agent can correct the migration into the safe form and resubmit, instead of either running the dangerous version or giving up. The guardrail teaches as it enforces.

The human angle

The same lint catches the migrations humans ship. Not everyone on a team has internalized the full list of locking and rewriting hazards, and the ones who have still miss them on a Friday afternoon. Running every migration through the lint means the team gets consistent review of the dangerous patterns, automatically, regardless of who wrote the DDL or how rushed they were.

It is the kind of check that is obvious in hindsight and easy to skip in the moment. Putting it at the wire means it does not get skipped.

Where it fits

Safe-migration linting pairs naturally with the other write-safety controls. Use it alongside human-in-the-loop approvals so that a flagged migration both gets the lint warning and waits for a human. Test the migration against an instant branch first, so you confirm it applies cleanly before it ever runs against production. And like every other decision, the lint result lands in the audit log: what was flagged, what was allowed, and what ran.

DDL is where a single statement carries the most risk. Linting it before it executes is the cheapest place to catch the mistake.

Try PgBeam or see the full feature set.

Give your agent Postgres it can't wreck

Connect a database, issue a credential, and watch the audit log fill up. No credit card. 14-day trial.