Neon Postgres Branching
When to Use
Use this skill when you need to choose and create the right Neon branch type for testing and development. Trigger keywords and scenarios include:
- "Create a Neon branch" / "branch my database"
- Migration testing against production-like data
- Isolated test or staging environments
- Schema-only branch workflows for sensitive or compliant data
- Reset-from-parent to refresh a drifted child branch
- Branch creation via Neon CLI, Neon MCP server, or Neon REST API
- Per-PR, per-test-run, or per-developer branching patterns
- Ephemeral branch lifecycle and expiration management
The outcome of this skill should be a created Neon branch (or a clear, actionable next step if creation cannot proceed). Choose the correct branch type, then execute branch creation via MCP or CLI.
- Normal branch — for realistic migration and query testing with real data.
- Schema-only branch (Beta) — for sensitive data workflows where structure is needed without copying rows.
Prerequisites
- Neon account and project — A Neon project must exist. Create one at https://console.neon.tech if needed.
- Authentication — At least one of the following must be available and authenticated:
- Neon MCP server — available and authenticated in an MCP-enabled environment. Docs: https://neon.com/docs/ai/neon-mcp-server.md
- Neon CLI — installed and authenticated. Verify with
neon --versionandneon projects list. Install via quickstart: https://neon.com/docs/reference/cli-quickstart - Neon REST API — a valid API key. Docs: https://neon.com/docs/guides/branching-neon-api.md
- Project context — Know your project ID. Set it once with
neon set-context --project-id <your-project-id>or pass--project-idon every command.
Procedure
Step 0 — Branch Type Decision
Apply this decision rule first:
- If the user wants to test complex migrations, performance, or behavior against production-like data → choose a normal branch.
- If the user needs to avoid copying sensitive data → choose a schema-only branch.
If the request is ambiguous, ask one clarifying question:
"Do you need realistic data for testing, or only schema structure because the data is sensitive?"
Step 1 — Tool Selection: CLI or MCP
Always support both Neon CLI and Neon MCP server. Prefer the tool the user already has installed and authenticated.
Selection order:
- Check MCP first in MCP-enabled environments:
- If Neon MCP tools are available and authenticated (e.g., listing projects works), use MCP.
- If MCP is unavailable or not authenticated, check CLI:
- Run
neon --versionto confirm CLI is installed. - Run
neon projects listto confirm auth/context.
- Run
- If CLI is missing, direct installation via quickstart: https://neon.com/docs/reference/cli-quickstart
- If CLI is installed but not authenticated, guide the user through
neon auth(or API key auth), then continue. - If both MCP and CLI paths are unsuccessful, use the Neon REST API: https://neon.com/docs/guides/branching-neon-api.md
MCP branch flow:
- Choose normal vs schema-only based on data sensitivity and migration-testing goals.
- Use branch tools (e.g.,
create_branch) to create the branch. - Validate with read tools (e.g.,
describe_branch). - For migration workflows, prefer branch-based migration flows before applying to main.
Step 2 — Create a Normal Branch (Preferred for Real-Data Migration Testing)
Use this when the user needs realistic testing conditions. Real production-like data can expose edge cases your seed or data migration scripts miss, which helps catch migration issues before going live.
Docs: https://neon.com/docs/introduction/branching.md
- Use MCP if already available/authenticated; otherwise verify CLI with
neon --version. - Ensure project context is set:
neon set-context --project-id <your-project-id> - Create the branch:
neon branches create \ --name <branch-name> \ --parent <parent-branch-id-or-name> \ --expires-at 2026-12-15T18:02:16Z - Optionally fetch a connection string for the new branch:
neon connection-string <branch-name>
Step 3 (Alternative) — Create a Schema-Only Branch (Beta, Sensitive Data)
Use this when users must not copy production rows into the test branch.
Docs: https://neon.com/docs/guides/branching-schema-only.md
- Use MCP if already available/authenticated; otherwise verify CLI with
neon --version. - Create the schema-only branch:
neon branches create \ --name <schema-only-branch-name> \ --parent <parent-branch-id-or-name> \ --schema-only \ --expires-at 2026-12-15T18:02:16Z - If multiple projects exist, include
--project-id:neon branches create \ --name <schema-only-branch-name> \ --parent <parent-branch-id-or-name> \ --schema-only \ --project-id <your-project-id> \ --expires-at 2026-12-15T18:02:16Z
Beta Support Guidance (Mandatory):
Schema-only branching is in Beta. If users report unexpected behavior, errors, or missing capabilities:
- Ask them to share feedback in the Neon Console: https://console.neon.tech/app/projects?modal=feedback
- Recommend opening a support conversation in the Neon Discord: https://discord.gg/92vNTzKDGp
Step 4 — Reset from Parent
Use this when a child branch has drifted and the user wants a clean refresh from the parent branch's latest schema and data.
Docs: https://neon.com/docs/guides/reset-from-parent.md
What it does:
- Fully replaces the child branch schema and data with the parent's latest state.
- Does not merge; local changes on the child branch are lost.
- Keeps the same connection details, but active connections are briefly interrupted during reset.
When to recommend it:
- Development or staging branch is too far behind production.
- User wants to start a new feature from a clean parent-aligned state.
- Team wants to refresh staging from production for consistent testing baselines.
Hard constraints and blockers:
- Only child branches can be reset (root branches and schema-only root branches cannot be reset from parent).
- If the target branch has children, reset is blocked until those child branches are removed.
- After a parent branch is restored from snapshot, reset-from-parent may be unavailable for up to 24 hours.
- Reset-from-parent always uses the current parent state; use Instant restore for point-in-time recovery needs.
CLI usage:
neon branches reset <id|name> --parent --preserve-under-name <backup-branch-name>
If project context is not already set, include project ID:
neon branches reset <id|name> --parent --preserve-under-name <backup-branch-name> --project-id <project-id>
--preserve-under-name keeps the pre-reset state as a backup branch for rollback, but adds one extra branch to clean up later.
Optional context setup to avoid repeating --project-id:
neon set-context --project-id <project-id>
Console and API usage:
- Console: Open the target child branch, then select Reset from parent from Actions.
- API: Use the restore endpoint for the branch and set
source_branch_idto the parent branch ID.
Step 5 — Post-Creation Environment Update
After branch creation, ask whether the user wants to update local environment credentials to point at the new branch.
- Ask: "Do you want me to update your
.envDATABASE_URLto this new branch connection string?" - If yes, write the new branch connection string to the requested env file/key.
- If no, leave credentials unchanged and share the connection string for manual use.
- Never overwrite an existing env key without explicit confirmation.
Step 6 (Optional) — Declarative Configuration with neon.ts
Beyond creating branches imperatively (CLI / MCP / API above), you can program what configuration new branches receive declaratively in neon.ts — Neon's infrastructure-as-code file. See the neon skill for the full reference.
Install:
npm i @neon/config
Example configuration:
// neon.ts
import { defineConfig } from "@neon/config/v1";
export default defineConfig({
branch: (branch) => {
if (branch.exists) return {}; // never reconcile existing branches
if (branch.isDefault) return { protected: true };
if (branch.name.startsWith("preview/") || branch.name.startsWith("dev")) {
return {
parent: "main",
ttl: "7d", // ephemeral: auto-expire 7 days after creation (max 30d)
postgres: {
computeSettings: {
autoscalingLimitMinCu: 0.25, // scale to zero
autoscalingLimitMaxCu: 1, // keep throwaway branches cheap
suspendTimeout: "5m",
},
},
};
}
return {};
},
});
The closure receives a read-only descriptor of the target branch — name, exists, isDefault, parentId, and more — and returns the tuning to apply: parent, ttl (auto-expiry), protected, and postgres.computeSettings. This is the declarative complement to ephemeral lifecycle hygiene and per-PR / per-test patterns: instead of remembering --expires-at on every neon branches create, the TTL and compute profile live in version control and apply to every matching branch.
Because neon checkout applies this policy when it creates a branch, a fresh preview/* or dev-* branch comes up already expiring and scaled-to-zero. Checking out an existing branch doesn't reconcile it — run neon deploy (alias for neon config apply) to apply changes to a branch that already exists.
Pitfalls
- Schema-only branches are independent root branches — they have no parent branch and no shared history, so reset-from-parent does not apply to them.
- Root branches cannot be reset from parent — only child branches support reset-from-parent.
- Reset blocked by child branches — if the target branch has children, reset is blocked until those child branches are removed.
- Reset unavailable after parent restore — after a parent branch is restored from snapshot, reset-from-parent may be unavailable for up to 24 hours.
- Reset is not a merge — local changes on the child branch are lost. Use
--preserve-under-nameto keep a backup. - Branch quota limits — root branch allowances and per-branch storage limits can cap how many schema-only branches users can create.
- Never overwrite env keys without confirmation — always ask before writing a new connection string to an existing
.envkey. - Schema-only is Beta — expect possible breaking changes or missing capabilities; direct users to Console feedback and Discord for issues.
neon checkoutdoes not reconcile existing branches — runneon deployto applyneon.tspolicy changes to branches that already exist.- TTL max is 30 days — the
ttlfield inneon.tssupports a maximum of30d. - Verify before destructive actions — always verify commands, API behavior, pricing, quotas, credentials, and deployment effects against current official documentation before making changes.
Verification
After branch creation, verify the branch exists and is accessible:
List branches to confirm creation:
neon branches listExpected: the new branch name appears in the output with the correct parent.
Describe the branch for details:
neon branches describe <branch-name>Expected: branch ID, parent branch, creation timestamp, and expiration (if set) are shown.
Fetch and test the connection string:
neon connection-string <branch-name>Expected: a valid PostgreSQL connection string is returned. Test connectivity with
psqlor your application's DB client.For MCP flows, use
describe_branchread tools to confirm the branch exists and has the expected parent and schema state.For schema-only branches, verify that tables exist but rows are not copied:
psql <connection-string> -c "\dt" psql <connection-string> -c "SELECT count(*) FROM <table_name>;"Expected: tables are listed; row counts are zero (or reflect only seed data if manually applied).
Examples
Example 1: Migration testing with realistic data
User input: "I need to test a risky migration against production-like data."
Agent output shape:
- Recommend a normal branch and explain why.
- Share docs link: https://neon.com/docs/introduction/branching
- Check the available/authenticated tool path first (MCP, otherwise CLI with
neon --version). - Provide commands:
neon branches create --name migration-test --parent main --expires-at 2026-12-15T18:02:16Z neon connection-string migration-test
Example 2: Sensitive data development workflow
User input: "We cannot copy production data because of compliance."
Agent output shape:
- Recommend schema-only branch and explain why.
- Share docs link: https://neon.com/docs/guides/branching-schema-only
- Check the available/authenticated tool path first (MCP, otherwise CLI with
neon --version). - Provide command:
neon branches create --name compliance-dev --parent main --schema-only --project-id <your-project-id> --expires-at 2026-12-15T18:02:16Z - Mention Beta support path:
Useful Workflow Patterns
If the user asks for process recommendations (not just a single command), suggest these:
- One branch per PR: Create branch when PR opens, delete when merged/closed, keep migration tests isolated.
- One branch per test run: Create branch at pipeline start, run migrations/tests, delete at end for deterministic CI.
- One branch per developer: Isolated dev environments with production-like shape; avoid team collisions on shared test data.
- PII-aware branching: If production has sensitive data, derive dev/PR branches from an anonymized branch or use schema-only branches.
- Ephemeral lifecycle hygiene: Set branch expiration and automate cleanup so old branches do not accumulate avoidable storage/history cost.
Branching in CI/CD
Common CI/CD use cases for Neon branches:
- Per-PR preview deployments: Branch on PR open, deploy the preview against it, delete on close. Each PR gets an isolated database branch. Injecting the branch's
DATABASE_URLinto the deployed app is hosting-provider-specific — see: - Migration testing in CI: Run risky schema changes against a branch with production-like data before merge.
- Schema diff visibility: Use the schema-diff GitHub Action to auto-comment a DB-layer diff on the PR.
Related skills
neon— Neon infrastructure-as-code (neon.ts) full reference, project configuration, and declarative branch policies.
Further reading
- https://neon.com/docs/guides/branch-expiration.md
- https://neon.com/docs/guides/neon-github-integration.md
- https://neon.com/docs/ai/neon-mcp-server.md
- https://neon.com/branching
Limitations
- Use this skill only when the task clearly matches its upstream product or API scope.
- Verify commands, API behavior, pricing, quotas, credentials, and deployment effects against current official documentation before making changes.
- Do not treat generated examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.