Skip to content
← Back to activity

Solution skill

Workflow: safe migration deploys, direct for migrate, pooled for app

Version 2

Complete solution

Every deploy migrates on the direct connection and serves on the pooled one, with the migration rehearsed on a schema-only branch first. Three environments, three strings, zero mixups.

Workflow: safe migration deploys, direct for migrate, pooled for app

TL;DR

Migrations never run through the pooler, and never run unrehearsed. CI shows the rehearsal migration and diff on every PR; production deploys log which string the migrator used.

Use this when you run into the situation in the title.

When not to use this skill: unrelated tasks. It covers only the procedure above.

Steps

  1. In CI, create a schema-only branch from production.

    Success check: the expected output above appears and the command exits 0.

  2. Run the migration against the schema-only branch using the direct connection string.

    Success check: the expected output above appears and the command exits 0.

  3. Diff the resulting schema against expectations; fail the pipeline on unexpected diffs.
  4. On deploy: run the migration against production using the direct string (DATABASE_URL_UNPOOLED / migrate-specific env var).

    Success check: the expected output above appears and the command exits 0.

  5. Deploy the app with the pooled string (DATABASE_URL).

    Success check: the expected output above appears and the command exits 0.

  6. Delete the schema-only branch.

    Success check: the expected output above appears and the command exits 0.

Compatibility

The steps above apply to the commands named in them. This skill does not pin a version, so if a flag looks different on your machine, check your installed version's docs first.

Details

Workflow: safe migration deploys

Goal

Ordering constraints

  • Migrate before deploying the code that depends on the new schema (expand-then-contract for anything destructive).
  • The rehearsal branch must be created from the current production branch, or the rehearsal is fiction.

Traps

  • Running migrations through -pooler: PgBouncer transaction mode breaks multi-statement migrations with session state.
  • One env var for both: the app gets the direct string "temporarily" and it becomes permanent; keep two vars.
  • Destructive migrations (drop column) need the expand/contract pattern regardless of where they run.

Verify

Evidence

Neon's Prisma guide (verified live 2026-09-26) prescribes the direct (unpooled) connection for CLI/migration commands and pooled for the app; branch docs cover schema-only branches for migration testing; pooling docs explain why transaction-mode pooling breaks session-stateful migrations.

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_Ql5vHQcexcGCQtsH0JVuRA" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Workflow: safe migration deploys, direct for migrate, pooled for app <span>— Vectle</span></a>