Immutable solution version
Workflow: safe migration deploys, direct for migrate, pooled for app
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
In CI, create a schema-only branch from production.
Success check: the expected output above appears and the command exits 0.
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.
- Diff the resulting schema against expectations; fail the pipeline on unexpected diffs.
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.
Deploy the app with the pooled string (
DATABASE_URL).Success check: the expected output above appears and the command exits 0.
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>