Neon Postgres for an exported site: connection strings, migrations and roles
Neon is one of the hosted Postgres options the exported Next.js app's README suggests, and it has a free tier that suits a first deployment. Getting it right comes down to three choices: the pooled or the direct connection string, how you run the two migrations, and which database role the app connects as.
Why Neon fits the export
The exported app needs ordinary Postgres and nothing vendor-specific, so any host works. Neon is convenient because a project and database exist within a minute of signing up, compute scales down when nobody is using it, and it pairs naturally with Vercel, which the README covers for deployment. Choosing Neon Postgres for exported site data is a reasonable default for a small business site that gets bursts of bookings rather than constant traffic.
Two connection strings
Neon gives every database a pooled string, whose host name contains -pooler, and a direct one without it. Neon's Prisma guide recommends the pooled string for the application, because serverless functions open many short connections, and the direct string for Prisma CLI commands such as prisma migrate, which need a direct connection for schema changes. Both examples in that guide end in ?sslmode=require; keep it.
The export's schema.prisma reads a single DATABASE_URL. That leaves two workable setups:
| Where the app runs | DATABASE_URL | Migrations |
|---|---|---|
| A long-running Node server | The direct string | Run normally; nothing else to change |
| Vercel or another serverless host | The pooled string | Add directUrl = env("DATABASE_URL_UNPOOLED") to the datasource and set that variable to the direct string, as Neon's guide describes for Prisma 6 |
The app's queries run inside short transactions that set the row-level security role with transaction-scoped settings, so they keep working through the pooler: each transaction carries its own role.
Step by step
- Create a Neon project and copy the connection details from its dashboard.
- In the exported project, copy
.env.exampleto.envand setDATABASE_URLas in the table above, plusENCRYPTION_KEY,OWNER_EMAIL,OWNER_PASSWORDandAPP_URL. - Run
npm install, then apply the migrations.npm run db:deployapplies the two shipped migrations without needing a shadow database;npm run db:migratealso works when your role may create databases. - Run
npm run db:seedto create the owner, then removeOWNER_PASSWORDfrom your environment. - Start with
npm run dev, sign in at/admin/loginand set up two-factor sign-in. - To deploy on Vercel, add the same variables there and use
npm run db:deploy && npm run buildas the build command, as the README says.
Check the role before you trust the policies
The export forces row-level security on every table, but Postgres lets superusers and roles with BYPASSRLS skip it. Neon's roles documentation lists BYPASSRLS among the privileges of neon_superuser (in projects created after August 2023) and says roles made in the Console, CLI or API are granted membership of it. Connect with the role you plan to use and run SELECT rolbypassrls FROM pg_roles WHERE rolname = current_user;.
If it returns true, the app still works and still checks roles itself, but the database layer isn't adding its protection. For the full benefit, create a login role with SQL (CREATE ROLE … LOGIN PASSWORD …), grant it select, insert, update and delete on the app's tables and usage on its sequences, check rolbypassrls is false for it, and use it in DATABASE_URL. Keep the original role for migrations. The reasoning is on the Postgres page.
Cold starts and timeouts
Neon compute that has scaled to zero takes a moment to wake. Neon's guide notes that Prisma can give up first with P1001: Can't reach database server, and suggests adding connect_timeout=15 to the connection string. For a site that's quiet at night, the first booking of the morning is the request most likely to hit it.
Limits and responsibilities
- Neon's free plan has its own limits on storage and compute; check Neon's pricing page rather than relying on figures here.
- Backups, branches and point-in-time restore are Neon features you configure, not part of the export.
- The export starts with empty tables. Submissions from your hosted Anticode site stay in its dashboard.
- If you upgrade to Prisma 7, the direct URL moves to
prisma.config.ts; follow Neon's and Prisma's guides.
Questions people ask
Can I use Neon branches for testing?
Yes. A branch is another Postgres database with its own connection string; point a development .env at it and run migrations there first.
Do I need the pooler for a small site?
On a long-running server, no; the direct string is fine. On serverless hosting, the pooled string avoids running out of connections.
Does Anticode connect to my Neon database?
No. Only the exported app does. Anticode's hosted sites use Anticode's own storage.
Sources
- Neon Docs: Connect from Prisma to Neon, checked
- Neon Docs: Manage roles, checked