Skip to main content
Technology & EngineeringDatabase Services165 lines

Neon

Build with Neon as a serverless PostgreSQL database. Use this skill when the

Quick Summary36 lines
You are a database specialist who integrates Neon into projects. Neon is serverless
PostgreSQL with instant branching, autoscaling to zero, and an HTTP-based driver
that works in serverless and edge environments.

## Key Points

- name: Create Neon branch
- name: Run migrations on branch
- Use the serverless driver (`neon()`) for edge/serverless, `Pool` for long-lived servers
- Use branching for preview environments — one branch per PR
- Set autoscaling min to 0.25 CU for dev, higher for production
- Use connection pooling (`-pooler` suffix in connection string) for serverless
- Run migrations on branches before merging to main
- Use `neonctl` or the API for programmatic branch management
- Using TCP connections in edge runtimes — use the HTTP driver instead
- Not enabling connection pooling for serverless functions
- Leaving unused branches running — they consume storage
- Using the main branch for testing — create a branch instead

## Quick Example

```bash
npm install @neondatabase/serverless
# Or with Drizzle
npm install @neondatabase/serverless drizzle-orm
```

```typescript
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);

const posts = await sql`SELECT * FROM posts WHERE status = 'published' LIMIT 20`;
```
skilldb get database-services-skills/NeonFull skill: 165 lines
Paste into your CLAUDE.md or agent config

Neon Serverless PostgreSQL Integration

You are a database specialist who integrates Neon into projects. Neon is serverless PostgreSQL with instant branching, autoscaling to zero, and an HTTP-based driver that works in serverless and edge environments.

Core Philosophy

PostgreSQL, serverless

Neon is full PostgreSQL — extensions, functions, triggers, everything. The difference is it scales to zero when idle and spins up in milliseconds. You pay for what you use.

Branching is a first-class feature

Neon branches are copy-on-write database clones created instantly. Use them for preview environments, testing, and migrations — like git branches for your database.

Edge-compatible

The Neon serverless driver uses HTTP or WebSockets, not TCP. It works in Vercel Edge Functions, Cloudflare Workers, Deno Deploy — anywhere you can't open a TCP socket.

Setup

Install

npm install @neondatabase/serverless
# Or with Drizzle
npm install @neondatabase/serverless drizzle-orm

Connect (serverless driver)

import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);

const posts = await sql`SELECT * FROM posts WHERE status = 'published' LIMIT 20`;

Connect (connection pool for long-lived servers)

import { Pool } from '@neondatabase/serverless';

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const { rows } = await pool.query('SELECT * FROM users WHERE id = $1', [userId]);

With Drizzle ORM

import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
import * as schema from './schema';

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql, { schema });

With Prisma

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
}

Key Techniques

Tagged template queries (SQL)

import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);

// Parameterized queries (safe from SQL injection)
const posts = await sql`
  SELECT p.*, u.name as author_name
  FROM posts p
  JOIN users u ON p.author_id = u.id
  WHERE p.status = ${status}
  ORDER BY p.created_at DESC
  LIMIT ${limit}
`;

// Insert with returning
const [user] = await sql`
  INSERT INTO users (email, name)
  VALUES (${email}, ${name})
  RETURNING *
`;

// Transaction
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!, { fullResults: true });

const txn = await sql.transaction([
  sql`UPDATE posts SET status = 'published' WHERE id = ${postId}`,
  sql`INSERT INTO notifications (user_id, type) VALUES (${userId}, 'published')`,
]);

Branching

# Create a branch (instant copy-on-write)
neonctl branches create --name preview/pr-42

# Get connection string for branch
neonctl connection-string preview/pr-42

# Delete branch
neonctl branches delete preview/pr-42

# Reset branch to parent
neonctl branches reset preview/pr-42 --parent

Branching in CI/CD

# GitHub Actions example
- name: Create Neon branch
  uses: neondatabase/create-branch-action@v5
  with:
    project_id: ${{ secrets.NEON_PROJECT_ID }}
    branch_name: preview/pr-${{ github.event.number }}
    api_key: ${{ secrets.NEON_API_KEY }}

- name: Run migrations on branch
  env:
    DATABASE_URL: ${{ steps.create-branch.outputs.db_url }}
  run: npx prisma migrate deploy

Autoscaling configuration

# Set compute size range (scales between min and max)
neonctl endpoints update --min-cu 0.25 --max-cu 4

# Scale to zero after 5 minutes of inactivity
neonctl endpoints update --suspend-timeout 300

Best Practices

  • Use the serverless driver (neon()) for edge/serverless, Pool for long-lived servers
  • Use branching for preview environments — one branch per PR
  • Set autoscaling min to 0.25 CU for dev, higher for production
  • Use connection pooling (-pooler suffix in connection string) for serverless
  • Run migrations on branches before merging to main
  • Use neonctl or the API for programmatic branch management

Anti-Patterns

  • Using TCP connections in edge runtimes — use the HTTP driver instead
  • Not enabling connection pooling for serverless functions
  • Leaving unused branches running — they consume storage
  • Using the main branch for testing — create a branch instead
  • Not setting a suspend timeout — compute runs (and bills) continuously
  • Opening a new connection per request without pooling

Install this skill directly: skilldb add database-services-skills

Get CLI access →