dev/notes
⌕

Spot a mistake? Highlight any text in a post and click Report — it goes straight to the author.

← all posts
intermediate · Databases · August 17, 2026 · 2 min read

How to Set Up a Serverless Postgres Database with Neon and Drizzle

Set up a serverless Postgres database with Neon and Drizzle ORM: schema, migrations, and queries without managing servers.

Serverless Postgres in minutes

Neon gives you a Postgres database with no server to provision — it scales to zero and branches like Git. Drizzle is a lightweight TypeScript ORM that maps your tables to types you can use end to end.

Step 1 — Create a Neon project

  1. Sign up at neon.tech and create a project.
  2. Copy the connection string — it looks like postgresql://user:[email protected]/neondb?sslmode=require.
  3. Store it as an environment variable, never in source:
DATABASE_URL="postgresql://..."

Step 2 — Install Drizzle

npm install drizzle-orm postgres
npm install -D drizzle-kit

Step 3 — Define a schema

src/db/schema.ts:

import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";

export const posts = pgTable("posts", {
  id: serial("id").primaryKey(),
  title: text("title").notNull(),
  body: text("body").notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

drizzle.config.ts:

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  dialect: "postgresql",
  dbCredentials: { url: process.env.DATABASE_URL! },
});

Step 4 — Generate and apply migrations

npx drizzle-kit generate
npx drizzle-kit migrate

generate diffs your schema into SQL files; migrate applies them to Neon. Commit the generated files — they’re your schema’s history.

Step 5 — Use Neon branches for staging

Neon’s killer feature is branching: you can fork your database instantly, which makes it practical to give every PR its own Postgres. The workflow looks like this:

  1. Branch the main database from the Neon dashboard or CLI.
  2. Point your staging environment at the branch’s connection string.
  3. Merge the branch back to main when the PR lands.

Because migrations are plain SQL files (from drizzle-kit generate), applying them to a fresh branch is the same npx drizzle-kit migrate — so a branch never drifts from production.

Step 6 — Query with type safety

src/db/index.ts:

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { posts } from "./schema";

const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client);

export async function listPosts() {
  return db.select().from(posts).orderBy(posts.createdAt);
}

The return type is inferred from the schema — rename a column and TypeScript flags every stale query.

Connection pooling for serverless

Serverless runtimes (Workers, serverless functions) open a new connection per invocation, which can exhaust Neon’s connection limit under load. Neon provides a pooled connection string for exactly this: same host, but it routes through PgBouncer-style pooling and lets thousands of short-lived connections share a handful of real ones.

Use the pooled URL in production serverless code, and the direct URL for migrations and local development. Drizzle doesn’t care which one you hand it — the connection string alone determines the behavior.

Troubleshooting

  • connect ECONNREFUSED / SSL errors — ensure the URL ends with ?sslmode=require.
  • Migration drift — never edit the database by hand; change the schema, regenerate, and migrate.
  • Too many connections — use Neon’s pooled connection string for serverless runtimes so you don’t exhaust the connection limit.

Summary

You have a managed Postgres database, a type-safe schema, and versioned migrations — with zero servers to operate. Put the migration command in CI and keep the database URL in the deployment environment, never in the repository. For a repeatable deployment pipeline, pair this guide with GitHub Actions for CI/CD.

Related posts

Comments

One comment per thread every 30 minutes · edits are unlimited.