Guide
Vercel preview branches
Wire a Vercel project's git branches to Layerbase databases. Your production branch points at your main database, and preview deployments run against an instant, copy-on-write database branch instead of your production data. By default every preview shares one staging branch forked from production; a mapping can instead use its own isolated preview branch, or per-branch mode, where each git branch gets a database branch of its own. The branch's pooled connection string is written to the environment variable you choose, so previews work with zero setup.
How it works
A Layerbase database branch is a full, writable copy of its parent. Once branching is on, a branch is created in seconds, not by a slow byte copy, so a preview gets its own data almost immediately. You connect Vercel once, map a project, and Layerbase keeps the wiring in sync:
- The production git branch uses your main database.
- The staging git branch uses a database branch forked from production.
- Every other git branch follows the mapping's Database source: it shares that staging branch by default, or gets an isolated preview branch when you pick one.
- The connection string is set on the Vercel environment variable you name (default
DATABASE_URL), scoped to the right deployment.
Preview branching works on every branchable engine: PostgreSQL, MySQL, MariaDB, Redis, Valkey, FerretDB, SQLite, libSQL, DuckDB, ClickHouse, QuestDB, InfluxDB, Qdrant, Meilisearch, Weaviate, and TypeDB. The injected value is that engine's own connection string, so the env var name is yours to choose. CouchDB and TigerBeetle cannot be branched (their cluster identity lives in the data).
Before you start
You need a database on a branchable engine on Layerbase Cloud and a Vercel project with a linked git repository. Branching also has to be turned on for the database, which is a one-click toggle (next step).
1. Turn on Instant branches
Open the database on Layerbase Cloud, go to its Settings tab, and turn on Instant branches. New databases on branchable engines usually have it on already, in which case the setting simply reads Enabled. If it is off, turning it on prepares the database for branching: that takes a few minutes once, and the database is briefly unreachable while it runs. Your connection string stays the same either way.
2. Connect Vercel
Go to Integrations and click Connect Vercel. You will be sent to Vercel to authorize Layerbase, then returned to the dashboard. The connection is shared with your team, so any member can wire up a project against it. You can also start from a database's Settings tab via Connect to Vercel, which deep-links straight into the wizard for that database.
3. Map a project
Click New mapping and fill in:
- Database: the production database to fork from.
- Vercel project: Layerbase reads its production branch for you.
- Environment variable name: defaults to
DATABASE_URL; change it to whatever your app reads. Layerbase writes the pooled connection string into it, which is what serverless functions need. - Also write
<NAME>_UNPOOLED(optional, off by default): a second variable carrying the direct connection string. Its name is derived from the variable name above with_UNPOOLEDappended, so the defaultDATABASE_URLgivesDATABASE_URL_UNPOOLED, and the toggle in the wizard shows the exact name it will write. See below. - Staging git branch and the name for the Layerbase staging branch to create.
- Optional toggles to write the env var on the production deployment and on the staging branch's preview deployments for you, instead of copying the value yourself.
On Create mapping, Layerbase ensures the database is branchable, forks the staging branch, and (if you opted in) writes the connection strings to Vercel. A production variable is set once and then left for you to manage; a staging variable is a Preview variable scoped to the staging git branch:
# Production deployment
DATABASE_URL=postgresql://user:pass@your-db.cloud.layerbase.dev/app?sslmode=verify-full
# Preview deployments on the "staging" branch
DATABASE_URL=postgresql://user:pass@your-db-staging.cloud.layerbase.dev/app?sslmode=verify-fullThe variables Layerbase writes carry sslmode=verify-full rather than the sslmode=require shown in the dashboard. Your Vercel app runs on Node, where verify-full verifies the certificate chain and hostname against the system trust store with no extra configuration, and it keeps doing so after a future pg major changes what require means. Connection strings you copy from the dashboard stay on require, which is the value every client accepts, including psql and GUI clients.
Pooled by default, direct on request
The variable Layerbase writes always carries the pooled connection string. Every Vercel function invocation opens its own connection, so an unpooled string is how a serverless app runs out of backend connections; Layerbase refuses to write one and tells you to retry if the pooler is momentarily missing.
Some Postgres features need a session that survives more than one statement, and a transaction pooler cannot carry them: LISTEN/NOTIFY, advisory locks, session settings, and long-lived prepared statements. For those, turn on Also write <NAME>_UNPOOLED in the wizard (or on an existing mapping via Edit); the toggle spells out the derived name for the variable you picked. Layerbase then writes a SECOND variable, named after your primary one with _UNPOOLED appended, carrying the direct connection string, everywhere it writes the first. With the default DATABASE_URL that pair looks like this:
# Pooled: what your app should use for normal queries
DATABASE_URL=postgresql://user:pass@your-db.cloud.layerbase.dev/app?sslmode=verify-full
# Direct: for LISTEN/NOTIFY, advisory locks, session-scoped work
DATABASE_URL_UNPOOLED=postgresql://user:pass@your-db.cloud.layerbase.dev:54321/app?sslmode=verify-fullThe companion's name is always derived from the primary one, so renaming the variable moves both. Turning the toggle off deletes the companion variables Layerbase created and leaves the primary untouched. Engines without a connection pooler have no separate direct endpoint, so there is nothing for the companion to carry and it is skipped. Most apps only need the pooled variable; leave the toggle off unless you know you need a session.
Existing environment variables
Layerbase never silently overwrites a variable you set by hand. When you pick a project in the wizard, it checks whether that variable name is already set on the scope it would write (production, or preview), and if so it warns you and leaves the toggle off. Turning the toggle on is your confirmation that Layerbase should take over that variable, replacing its value and managing (and eventually deleting) it. In per-branch mode, if a git branch already has that variable configured manually on Vercel, Layerbase skips creating a preview database for that branch rather than clobber your value; remove the manual variable, or change the integration's variable name, to let the automation take over.
Where preview deployments get their database
Deploys of your staging git branch always use the staging branch. Every other branch follows the mapping's Database source: they can share that same staging branch (the default), or use a separate preview branch forked from production or from staging, so preview work never writes into staging data.
You can change this later without recreating the mapping: open Edit and pick a different Database source. Layerbase re-scopes the variables it manages in place, so your production variable is never removed and no database branch is destroyed. Switching back to the shared staging branch keeps the preview branch you already had; delete it from its dashboard page if you no longer need it. Switching between the two fork sources records the new one for the next reset and leaves the existing preview branch alone. Per-branch mode stays a create-time choice: switch to or from it by removing the mapping and creating it again.
Renaming the environment variable
Open Edit on a mapping and change the Environment variable name. Layerbase rewrites every variable it manages for that project under the new name (staging, preview, any per-branch variables, and the _UNPOOLED companions when they are enabled), then removes the old ones. Your database branches are untouched, so the rename costs nothing: no re-fork, no data loss. The Production variable is set once and never re-managed, so it only moves when Layerbase was the one that set it; otherwise it is left exactly as it is and the result message says so. Make sure your app reads the new name before you rename - deployments pick it up on their next build, not retroactively.
Reset staging on every deploy (optional)
Turn on Reset staging on merge to re-fork the staging branch from production whenever the staging branch deploys. This keeps staging close to production, and is destructive: it discards whatever was in the staging branch. The connection string does not change, so nothing downstream needs re-wiring. It is off by default.
The reset runs before the build, not during it. On a push, Layerbase cancels the deployment Vercel just started, re-forks the branch, then redeploys the same commit, so build-time migrations run after the reset against a branch that is already fresh. You will see one canceled deployment followed by the real one for every push that triggers a reset. This needs the integration's deployment permission: if you connected Vercel before August 20, 2026, reconnect it from the Integrations page. Without that permission the reset still happens, it just runs alongside the build, which is the old behavior, so a retry around a build-time migration stays a sensible belt and braces for any connection that could predate the reset.
Removing a mapping
Delete a mapping from the Integrations page. Layerbase removes the preview environment variable it created. Your production variable and the Layerbase staging branch are left untouched; delete the branch from its dashboard page if you want it gone. Mark any database or branch as persistent on its Settings tab to protect it from automated cleanup entirely.
Other ways to set up
Prefer to wire it yourself? The same database-branch API powers two other paths: a drop-in GitHub Actions workflow that creates and tears down a branch per pull request, and a paste-able AI-agent prompt that sets it up against the API for you. Both converge on the same primitive (a parent database plus the branch API), so you can move between them without re-architecting.