Data API
buildingWhich endpoint to point your migration tool at, and why it matters.
Running migrations
Point your migration tool at the direct connection string, not the pooled one.
DATABASE_URL="$DIRECT_URL" npx drizzle-kit migrate
DATABASE_URL="$DIRECT_URL" npx prisma migrate deploy
DATABASE_URL="$DIRECT_URL" bundle exec rails db:migrateWhy not the pooled one
The pooler runs in transaction mode: a connection is handed back to the pool
between statements, so anything relying on session state across statements
breaks. Migrations rely on exactly that — advisory locks that stop two deploys
migrating at once, SET statements that configure a session, and long
transactions holding DDL.
Some tools notice and fail clearly. Others succeed and leave a lock nobody holds, which is worse. The direct endpoint has none of these problems and a migration is a single connection for a short time, which is what it is for.
Two variables is the normal shape
Most frameworks expect this now:
1DATABASE_URL="postgresql://…-pooler…" # the app2DIRECT_URL="postgresql://…" # migrationsPrisma names it directUrl in the datasource block; Drizzle takes whatever you
pass its config. Both fetchable from
GET /v1/data/_connection.
Long migrations and sleeping
A database wakes on the first connection, so a migration on a sleeping database pays a second or so before its first statement. Nothing else is different — the compute stays up for the whole run and for five minutes after.
A migration that rewrites a large table can outgrow the compute ceiling of four CU. If one is unusually slow, that is worth telling us about rather than waiting: the ceiling is per project and raisable.
We do not run them for you
No migration is applied to your database by us, ever. Nothing of ours lives in it — no schema, no tables, no extension we depend on — which is what makes it safe for you to be its owner and what makes upgrades on our side invisible to you.