dev/notes

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

intermediate · Databases · August 17, 2026 · 1 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 — 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.

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.

Related posts

Comments

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