Anticode Open builder

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.

Updated · By the Anticode team

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:

Choosing a setup
Where the app runsDATABASE_URLMigrations
A long-running Node serverThe direct stringRun normally; nothing else to change
Vercel or another serverless hostThe pooled stringAdd 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

  1. Create a Neon project and copy the connection details from its dashboard.
  2. In the exported project, copy .env.example to .env and set DATABASE_URL as in the table above, plus ENCRYPTION_KEY, OWNER_EMAIL, OWNER_PASSWORD and APP_URL.
  3. Run npm install, then apply the migrations. npm run db:deploy applies the two shipped migrations without needing a shadow database; npm run db:migrate also works when your role may create databases.
  4. Run npm run db:seed to create the owner, then remove OWNER_PASSWORD from your environment.
  5. Start with npm run dev, sign in at /admin/login and set up two-factor sign-in.
  6. To deploy on Vercel, add the same variables there and use npm run db:deploy && npm run build as 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

  1. Neon Docs: Connect from Prisma to Neon, checked
  2. Neon Docs: Manage roles, checked