name: "Neon Serverless PostgreSQL" description: "Configure serverless PostgreSQL databases on Neon with connection pooling, branching, and Edge Function integration. Apply when setting up serverless databases, connecting from Edge Functions, or managing database branches." allowed-tools: Read, Write, Edit, Bash version: 1.1.0 compatibility: Claude Opus 4.5, Claude Code v2.x updated: 2026-01-24
Neon Serverless PostgreSQL
Systematic Neon database setup for serverless applications with cost optimization and performance.
Overview
This Skill enforces:
- Serverless PostgreSQL setup
- Connection pooling and HTTP connection mode
- Database branching for development
- Environment variable configuration
- Edge Function integration (Vercel, Netlify, Cloudflare)
- Zero-downtime deployments
- Autoscaling configuration
Apply when setting up serverless databases, connecting from Edge Functions, or managing environments.
Neon Workflow
Every Neon setup follows this process:
Step 1: Create Neon project
↓
Step 2: Get connection string
↓
Step 3: Set up database branches
↓
Step 4: Configure for environment
↓
Step 5: Connect from application
↓
Step 6: Set up autoscaling
Step 1: Create Neon Project
Sign Up and Create Project
- Visit https://neon.tech
- Sign up with GitHub or email
- Click "Create Project"
- Choose region (closest to your users)
- Select PostgreSQL version (14, 15, 16)
Get Connection Details
Connection string format:
postgresql://[user]:[password]@[host].neon.tech/[dbname]?sslmode=require
Step 2: Connection Modes
Pooler Connection (Recommended for Edge Functions)
postgresql://[user]:[password]@[host]-pooler.neon.tech/[dbname]?sslmode=require
Why pooler for Edge Functions:
- Connection pooling (many connections share few TCP connections)
- Optimized for serverless (many short-lived connections)
- Lower latency
- Cost-effective
Regular Connection (For long-lived connections)
postgresql://[user]:[password]@[host].neon.tech/[dbname]?sslmode=require
Step 3: Environment Configuration
Local Development
Create .env.local:
DATABASE_URL="postgresql://[user]:[password]@[host]-pooler.neon.tech/[dbname]?sslmode=require"
Add to .gitignore:
.env.local
.env.*.local
Vercel Environment Variables
Set in Vercel dashboard → Settings → Environment Variables:
DATABASE_URL (for all environments: Development, Preview, Production)
GitHub Secrets (for CI/CD)
DATABASE_URL
NEON_API_KEY
Step 4: Database Branching
Create Development Branch
# Using Neon CLI
neon branches create --name development
# Get development database connection string
neon connection-string development
Git-like Branching Workflow
main (production database)
↓
development (feature development)
↓
feature-x (isolated testing)
Benefits:
- Data isolation between environments
- Test migrations safely
- Reset databases quickly
- PR previews with separate databases
Manage Branches
# List all branches
neon branches list
# Create branch from main
neon branches create --name staging --parent main
# Delete branch
neon branches delete development
# Reset branch to main state
neon branches delete feature-x
neon branches create --name feature-x --parent main
Step 5: Connection Strategies
For Next.js API Routes (Server-side)
// lib/db.ts
import { Pool } from '@neondatabase/serverless';
import ws from 'ws';
// Set WebSocket constructor for Node.js < 21
if (typeof global !== 'undefined' && !global.WebSocket) {
global.WebSocket = ws as any;
}
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});
export async function query(sql: string, params: unknown[] = []) {
const client = await pool.connect();
try {
return await client.query(sql, params);
} finally {
client.release();
}
}
For Vercel Edge Functions
// api/edge-query.ts
import { neon } from '@neondatabase/serverless';
export const config = {
runtime: 'edge',
regions: ['iad1'] // Closest to Neon
};
export default async (req: Request) => {
const sql = neon(process.env.DATABASE_URL!);
const [user] = await sql`SELECT * FROM users WHERE id = ${123}`;
return new Response(JSON.stringify(user), {
headers: { 'content-type': 'application/json' }
});
};
For Netlify Functions
// netlify/functions/query.ts
import { neon } from '@neondatabase/serverless';
export default async (event: any) => {
const sql = neon(process.env.DATABASE_URL!);
const users = await sql`SELECT * FROM users LIMIT 10`;
return {
statusCode: 200,
body: JSON.stringify(users)
};
};
For Cloudflare Workers
// src/index.ts
import { neon } from '@neondatabase/serverless';
export default {
async fetch(request: Request, env: any) {
const sql = neon(env.DATABASE_URL);
const [post] = await sql`SELECT * FROM posts WHERE id = ${1}`;
return new Response(JSON.stringify(post), {
headers: { 'content-type': 'application/json' }
});
}
};
Step 6: Autoscaling Configuration
Set Compute Auto-Suspend
Neon automatically pauses compute when unused (saves costs):
Settings → Compute Options
- Auto-suspend: 5 minutes (default)
- Auto-suspend delay: Can be customized
Set Connection Pooling Limits
Settings → Pooler Settings
- Pool size: 10-100 connections
- Connection timeout: 30s
Step 7: Database Operations
Create Tables
-- Using Neon SQL Editor or psql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_users_email ON users(email);
Query from Node.js
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
// Single row query
const [user] = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Multiple rows
const users = await sql`SELECT * FROM users LIMIT 10`;
// Insert
const [newUser] = await sql`
INSERT INTO users (email, name)
VALUES (${email}, ${name})
RETURNING *
`;
// Update
const [updated] = await sql`
UPDATE users
SET name = ${name}
WHERE id = ${userId}
RETURNING *
`;
// Delete
await sql`DELETE FROM users WHERE id = ${userId}`;
Anti-Patterns
// ❌ BAD: Creating Pool outside request handler
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export async function GET(req: Request) {
const client = await pool.connect(); // Reuses connections
// ...
}
// ✅ GOOD: Create Pool inside request handler
export async function GET(req: Request) {
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const client = await pool.connect();
try {
// Query
} finally {
await client.release();
await pool.end();
}
}
// ❌ BAD: Connection string in code
const sql = neon('postgresql://user:password@host/db');
// ✅ GOOD: Use environment variable
const sql = neon(process.env.DATABASE_URL!);
// ❌ BAD: Forgetting to close connections
const client = await pool.connect();
const result = await client.query('SELECT * FROM users');
// No release!
// ✅ GOOD: Always release connection
const client = await pool.connect();
try {
const result = await client.query('SELECT * FROM users');
} finally {
client.release();
}
Connection Troubleshooting
Connection Timeout
# Issue: Taking too long to connect
# Solution: Use pooler connection instead of direct connection
# Change: host.neon.tech → host-pooler.neon.tech
SSL Certificate Error
# Issue: SSL certificate validation failed
# Solution: Add sslmode=require to connection string
DATABASE_URL="postgresql://...?sslmode=require"
Too Many Connections
# Issue: Error: too many connections
# Solution: Enable connection pooling or increase pool size
Backup and Recovery
Automatic Backups
Neon automatically backs up every transaction. Access via:
- Neon console → Branches → branch name
- Under "Backups" section
- Restore from point-in-time
Manual Export
# Export data
pg_dump postgres://user:password@host/db > backup.sql
# Restore data
psql postgres://user:password@host/db < backup.sql
Verification Before Production
- Connection string configured in environment variables
- Pooler connection used for Edge Functions
- Database branches set up (main, development, staging)
- Connection pooling enabled
- Autoscaling configured
- Secrets not hardcoded
- SSL mode enabled (sslmode=require)
- Backups tested
- Read replicas configured (if needed)
- Monitoring alerts set up
Common Operations
# Get connection string
neon connection-string
# List databases
neon databases list
# Get branch list
neon branches list
# Create backup
pg_dump $DATABASE_URL > backup.sql
# Restore from backup
psql $DATABASE_URL < backup.sql
# Reset branch (delete all data)
neon branches delete branch-name
neon branches create --name branch-name --parent main
Integration with Project Standards
Enforces database best practices:
- D-1: Database models defined
- D-2: Validation at API and DB layers
- S-5: Environment variables for secrets
- No hardcoded credentials
- Connection pooling for efficiency
Resources
- Neon Documentation: https://neon.tech/docs
- Serverless Driver: https://github.com/neondatabase/serverless
- Connection Pooling: https://neon.tech/docs/connect/connection-pooling
- Branching: https://neon.tech/docs/guide/branch
Last Updated: January 24, 2026 Compatibility: Claude Opus 4.5, Claude Code v2.x Status: Production Ready
January 2026 Update: This skill is compatible with Claude Opus 4.5 and Claude Code v2.x. For complex tasks, use the
effort: highparameter for thorough analysis.