← Writing

On serverless, run database migrations at deploy time — never at boot

A serverless function boots on every cold start; migrations belong in the build step, where they run exactly once per deploy against the production database.

Classic server apps often run pending migrations at boot. On serverless that instinct is a footgun: your “boot” happens on every cold start, concurrently, on whatever instance wakes up first. Migrations racing each other from lambda cold starts is not a place you want to be.

The pattern that works: run migrations in the build step. On Netlify, the build environment gets the production database URL injected (NETLIFY_DATABASE_URL with their Neon integration), so the build can apply pending Drizzle migrations plus idempotent seeds exactly once per deploy — before the new function version ever ships:

# netlify.toml
command = "cd backend && npm install && npm run db:migrate && npm run db:seed && cd ../web && npm run build"

The function itself never touches migration code. A deploy either migrates and ships together, or fails together — no half-migrated running version.

← All writing Book a call →
Book a call → WhatsApp