Neon is serverless PostgreSQL that auto-scales, scales to zero when idle, and lets you branch your database like git branches. Free tier: 0.5 GiB storage, autosuspend after 5 min inactivity.
Why Neon?
- Scale to zero — pay nothing when idle
- Branching — create database copies instantly (like git branch)
- Serverless driver — HTTP/WebSocket, works in edge functions
- It's PostgreSQL — 100% compatible, all extensions work
- Free tier — 0.5 GiB, 190 compute hours/month
Quick Start
# Sign up at console.neon.tech
# Get connection string: postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/neondb
# Standard psql works
psql 'postgresql://user:pass@ep-xxx.us-east-2.aws.neon.tech/neondb?sslmode=require'
Serverless Driver (Edge/Serverless)
import { neon } from '@neondatabase/serverless';
// Works in Cloudflare Workers, Vercel Edge, Deno Deploy!
const sql = neon(process.env.DATABASE_URL!);
// Query
const users = await sql`SELECT * FROM users WHERE active = true`;
// Parameterized
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Insert
await sql`INSERT INTO users (name, email) VALUES (${name}, ${email})`;
// Transaction
const { neonConfig } = await import('@neondatabase/serverless');
import { Pool } from '@neondatabase/serverless';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query('INSERT INTO orders (user_id, total) VALUES ($1, $2)', [userId, 99.99]);
await client.query('UPDATE users SET order_count = order_count + 1 WHERE id = $1', [userId]);
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
Neon API (Management)
API="https://console.neon.tech/api/v2"
TOKEN="your-api-key"
# List projects
curl $API/projects -H "Authorization: Bearer $TOKEN"
# Create branch (instant database copy!)
curl -X POST "$API/projects/PROJECT_ID/branches" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"branch": {"name": "feature-new-auth"}}'
# List branches
curl "$API/projects/PROJECT_ID/branches" \
-H "Authorization: Bearer $TOKEN"
# Delete branch
curl -X DELETE "$API/projects/PROJECT_ID/branches/BRANCH_ID" \
-H "Authorization: Bearer $TOKEN"
# Get connection URI
curl "$API/projects/PROJECT_ID/connection_uri?branch_id=BRANCH_ID&database_name=neondb&role_name=neondb_owner" \
-H "Authorization: Bearer $TOKEN"
Branching Workflow
# Main database: production data
# Branch: test migrations, preview deploys, dev work
# Create branch for feature
neon branches create --name feature-auth --project-id xxx
# Get connection string for branch
neon connection-string feature-auth --project-id xxx
# Use in your feature branch CI
DATABASE_URL=$(neon connection-string feature-auth) npm test
# Merge to main? Delete branch
neon branches delete feature-auth --project-id xxx
Drizzle ORM + Neon
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);
const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
createdAt: timestamp('created_at').defaultNow(),
});
// Type-safe queries
const allUsers = await db.select().from(users);
const newUser = await db.insert(users).values({ name: 'Alice', email: 'alice@example.com' }).returning();
Key Features
| Feature | Details |
|---|---|
| Engine | PostgreSQL 16 |
| Scale to zero | Auto-suspend after 5 min |
| Branching | Instant copy-on-write |
| Driver | HTTP, WebSocket, TCP |
| Extensions | pgvector, PostGIS, etc. |
| Free tier | 0.5 GiB, 190 compute hrs |
Resources
Building serverless apps? Check my Apify actors or email spinov001@gmail.com.
Top comments (0)