Data API

building

Which 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.

bash
DATABASE_URL="$DIRECT_URL" npx drizzle-kit migrate
DATABASE_URL="$DIRECT_URL" npx prisma migrate deploy
DATABASE_URL="$DIRECT_URL" bundle exec rails db:migrate

Why 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:

.env
1DATABASE_URL="postgresql://…-pooler…"   # the app2DIRECT_URL="postgresql://…"             # migrations

Prisma 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.