PostgreSQL owns tenant state, durable queues, authentication, and accounting. The application uses its existing SQL migrations and Better Auth schema. Neon Auth, Data API, Functions, and Object Storage are not required: authentication runs in the application, hosting uses Vercel, and project files use R2. Register the application domain with Vercel/DNS and configure its OAuth origin in the application; no additional Neon application-domain registration is needed.
Create an isolated environment
Create a Neon project and database in a region near the application. Use separate staging and production branches or projects with explicitly reviewed data access. Prefer schema-only branches for tests that do not need customer data.
Retain the provider's owner credential for migrations. Create a separate SQL runtime role with LOGIN, NOBYPASSRLS, no superuser, no role/database creation, no replication privilege, and no inherited administrative membership. The runtime must not own application tables. Set its password privately using your SQL client's protected password facility.
For a new database, the following SQL creates that role without supplying a password in command history. Run it once as the database owner, then use the SQL client’s protected password prompt (for example, \password platform_app in psql). Do not recreate or reset a role in an existing installation.
CREATE ROLE platform_app LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE
NOINHERIT NOBYPASSRLS NOREPLICATION;
The migrations also use a NOLOGIN platform_reporting role for bounded operator views. The migration owner needs the privileges required by the reviewed migrations to create and assign that role; do not grant its membership to the serving runtime.
Configure connections
| Variable | Role and connection |
|---|---|
DATABASE_URL | Restricted runtime role, pooled endpoint, TLS |
AUTH_DATABASE_URL | Same restricted role, direct endpoint, TLS |
MIGRATION_DATABASE_URL | Database owner, direct endpoint, TLS; admin only |
The domain uses transaction-local tenant context. pnpm db:migrate installs one-minute statement and two-minute idle-transaction deadlines on the runtime role in the target database. Domain/credential connections send no timeout startup options: Neon transaction pooling rejects them. Keep AUTH_DATABASE_URL direct, run the migration command before deploying, and reconnect existing database backends after changing role defaults. The migration owner needs permission to alter that runtime role; do not grant the runtime administrative privileges. Identity connections set the auth,public search path at startup; the Neon pooler rejects this startup option, so identity uses the direct endpoint. Never substitute an owner URL to work around a runtime connection error.
Apply the schema
Use the ordered migrate.ts, auth-migrate.ts, and provision-cli.ts commands in deployment. Configure the final application origin and retained auth/vault keys before OAuth provisioning.
For upgrades, compare the current schema_migrations records with the release's numbered SQL files. Rehearse unapplied forward migrations on an isolated branch. Existing numbered migrations are immutable after release. Do not reset or seed a database containing customer accounts.
After migration, verify forced tenant RLS, restricted journal mutation, and authentication with the runtime role. Confirm that a request in one organization cannot read another organization's resources.
Use the Neon CLI deliberately
If you use the Neon CLI, select the intended project and branch explicitly. Use --no-env-pull with link, checkout, and deploy operations to preserve the local simulator environment. Neon policy deployment does not run this application's SQL migrations or deploy the dashboard.
The repository's neon.ts has an empty policy. It does not provision additional Neon services. Operator CLI/MCP credentials belong in private tooling configuration, never in the application or native agent environment.
Production recovery safeguards
Before accepting customer data, select a recovery window that covers delayed discovery of accidental changes. Seven days is the recommended starting target for this deployment. In Neon Console, open Settings → Instant restore → History window, select seven days, save, and verify the effective value. The current Free plan caps history at six hours; Launch supports up to seven days and Scale up to thirty. An upgrade alone does not establish a seven-day setting. Recheck existing compute limits and project defaults after upgrading; the provider can raise their autoscaling ceilings. Longer retained history has a usage cost, and extending the setting cannot recover history already discarded. See Neon's history-window reference.
On a paid plan, open the production branch and select Protect. Verify the protected designation before launch. This blocks branch deletion/reset and protects associated project/compute deletion; it does not prevent SQL writes, dropped tables, or application mistakes. New branches created from a protected parent receive different role passwords, so retrieve each branch's own connection credentials. See protected branches.
Rehearse point-in-time recovery in an isolated environment with a known before/after marker and verify schema, records, tenant permissions, and application access after recovery. Current Neon guidance limits instant restore to root branches; a child branch used for migration rehearsal is not proof of root-branch PITR. Record the actual recoverable interval and recovery time. Do not reset the serving production branch as a test. Follow Neon's restore procedure.
PITR restores database state, not R2 objects or vault keys. Retain and test the matching encrypted objects and decrypt keys independently. Keep outstanding account-specific safeguards in the release TODO.
Capacity and recovery
Budget the sum of domain, identity, and credential-refresh connections across application instances. Inspect query latency, active connections, queue age, and provider compute headroom before increasing execution concurrency.
Monitor CPU, connection usage, database/history storage growth, query latency, and billed compute time. The application's minutely maintenance and dashboard/worker polling can prevent the idle interval needed for suspension. Budget for the observed active time rather than assuming scale-to-zero savings; see Neon's suspension behavior.
Pause an unused staging environment
Keep production maintenance running. To stop an isolated staging environment from consuming continuous database compute:
- Confirm staging has no active or queued runs, pending dispatch or workspace operations, unsettled billing orders, or reserved funds. Stop acceptance tests and review any incoming integrations or schedules before pausing.
- In the staging Vercel project, open Settings → Cron Jobs and disable cron execution. Then open Settings → General → Pause Project. Pausing preserves the deployment but returns
503 DEPLOYMENT_PAUSEDto visitors. See Vercel project pause/resume. - Allow the staging Neon compute to suspend, or suspend it through the Neon API. Verify its state is
idlethrough the control plane; querying the database itself wakes it. Retain storage and credentials. - Record the project identities, previous cron setting, compute limits and resume steps privately. Keep staging paused between test sessions; deployments and direct database clients can otherwise generate activity.
To resume, unpause the same Vercel project and re-enable its cron jobs. Database connections resume an idle Neon compute automatically. Verify health and maintenance, then inspect overdue schedules, queued deliveries and billing reconciliation before starting tests. Do not repeatedly resend events whose outcomes are unknown.
An organization plan upgrade also changes staging's compute billing. At Launch's published rate, one continuously active 0.25-CU compute costs about $19.35 in a 730-hour month; two cost about $38.69, before storage and recovery history. These are usage estimates, not spending caps. A fixed compute ceiling constrains compute charges but does not cap storage, network or other providers. See Neon pricing.
Recover from a consistent database point together with all referenced encrypted objects and retained vault keys. Rehearse restoration in an independent environment. See scaling, hosting, and the maintainer database verification record.