Neon is a serverless Postgres platform that autoscales to zero when idle and scales up instantly on demand. The free tier is generous enough to build a real application, and the branching feature makes it uniquely suited to AI development workflows. This guide covers setup through first query.
Why Neon for AI Apps
- Scales to zero — no cost when your app is idle (weekends, low-traffic periods)
- Database branching — create an isolated copy of your database per pull request
- Built-in connection pooling via pgBouncer — handles the connection limits of serverless environments
- pgvector support — add vector search without leaving Postgres
- Compatible with all Postgres ORMs: Drizzle, Prisma, SQLAlchemy
Step 1: Create a Project
- Go to neon.tech and sign up
- Click New Project
- Choose a region (pick the one closest to your hosting provider)
- Neon creates a database, default branch (main), and connection string in under 5 seconds
Step 2: Get Your Connection String
Neon provides two connection strings: a direct connection and a pooled connection. For serverless environments (Vercel, Netlify, Cloudflare Workers), always use the pooled connection string.
# Direct connection — use for migrations only
postgresql://user:password@ep-abc123.eu-west-2.aws.neon.tech/neondb
# Pooled connection — use in your application
postgresql://user:password@ep-abc123-pooler.eu-west-2.aws.neon.tech/neondb?pgbouncer=true
# Set in your environment
DATABASE_URL=postgresql://user:password@ep-abc123-pooler.../neondb?pgbouncer=trueNever use the direct connection string in serverless function code. Serverless functions can open hundreds of connections simultaneously; the pooler caps this to a safe limit. Using the direct string will exhaust Postgres connection slots.Step 3: Connect with Drizzle ORM
npm install drizzle-orm @neondatabase/serverless
npm install -D drizzle-kit// lib/db.ts
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
import * as schema from './schema';
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });// lib/schema.ts
import { pgTable, uuid, text, timestamp } from 'drizzle-orm/pg-core';
export const documents = pgTable('documents', {
id: uuid('id').primaryKey().defaultRandom(),
title: text('title').notNull(),
content: text('content').notNull(),
createdAt: timestamp('created_at').defaultNow(),
});Step 4: Run Migrations
# Generate migration SQL from your schema
npx drizzle-kit generate
# Apply migrations to the database
npx drizzle-kit migrate
# Or push schema directly (development only)
npx drizzle-kit pushRun migrations against the direct connection string, not the pooled one. Set a separate DATABASE_URL_DIRECT in your environment for migration scripts.Step 5: Query Your Database
// app/api/documents/route.ts
import { db } from '@/lib/db';
import { documents } from '@/lib/schema';
export async function GET() {
const docs = await db.select().from(documents).limit(20);
return Response.json(docs);
}
export async function POST(req: Request) {
const { title, content } = await req.json();
const [doc] = await db.insert(documents).values({ title, content }).returning();
return Response.json(doc, { status: 201 });
}Autoscale-to-Zero: What to Expect
On the free tier and lower paid tiers, Neon scales your compute to zero after 5 minutes of inactivity. The next query 'wakes' the database with a cold start of 500ms–3 seconds. This is not noticeable in interactive workflows but may affect scheduled jobs that run infrequently.
To disable autoscale-to-zero, upgrade to a plan that supports always-on compute or use the Neon API to keep the compute awake with periodic pings.
| Metadata | Value |
|---|---|
| Title | Getting Started with Neon Serverless Postgres: Setup, Connection, and First Query |
| Tool | Neon |
| Primary SEO keyword | neon serverless postgres setup |
| Secondary keywords | neon database tutorial, neon drizzle orm, neon connection string, neon next.js |
| Estimated read time | 8 minutes |
| Research date | 2026-04-14 |