drizzle-kit push vs Migrations in Drizzle ORM

From the Drizzle ORM cheat sheet · Migrations · verified Jul 2026

drizzle-kit push vs Migrations

When to use push (fast iteration) vs generate + migrate (versioned, prod-safe)

bash
# Fast iteration — diff schema and push to the DB directly
npx drizzle-kit push           # no SQL files, no history; great for local/dev

# Versioned migrations — generate SQL, commit it, then apply
npx drizzle-kit generate       # writes drizzle/<timestamp>_<name>.sql
npx drizzle-kit migrate        # applies pending migration files

# Other useful kit commands
npx drizzle-kit studio         # browse + edit data at localhost:4983
npx drizzle-kit check          # verify migration files are consistent
npx drizzle-kit up             # rewrite drizzle metadata after manual edits

# DETAILED_TAB:
# ===== drizzle-kit push =====
# What it does: diffs your schema.ts against the live DB and runs the
# resulting ALTERs immediately. No SQL files written. No history.
#
# Use when:
#   - Local dev where the schema is still in flux
#   - A throwaway preview branch
#   - You don't need an audit trail of how the schema evolved
#
# Don't use in production — there's no replayable record of changes.
npx drizzle-kit push
npx drizzle-kit push --verbose            # show every SQL statement
npx drizzle-kit push --strict             # confirm potentially destructive ops

# ===== drizzle-kit generate + migrate =====
# What it does:
#   generate → diffs schema.ts and writes a numbered .sql file
#              into your migrations folder
#   migrate  → applies all unapplied files in order, tracked in a
#              __drizzle_migrations table
#
# This is the production workflow. Commit the SQL files to git so
# every deploy sees the same migration history.

# 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! },
})

# Workflow
npx drizzle-kit generate --name=add_posts_table   # writes 0001_add_posts_table.sql
git add drizzle/
git commit -m 'migration: add posts table'
npx drizzle-kit migrate                            # apply locally / in CI

# Programmatic migrate (e.g. in a CI step or app startup)
import { migrate } from 'drizzle-orm/node-postgres/migrator'
await migrate(db, { migrationsFolder: './drizzle' })

# ===== Hybrid pattern that works for most teams =====
#   - Local dev: npx drizzle-kit push for fast iteration
#   - Before PR: npx drizzle-kit generate to capture the final shape
#   - CI / prod: npx drizzle-kit migrate from the generated SQL files
💡 push = no SQL files, fast loops; migrate = versioned, replayable, prod-safe
⚠️ Never use push in production — there is no audit trail of changes
📌 Commit the generated SQL files in /drizzle so every env converges
🎯 Common pattern: push locally → generate before PR → migrate in CI
migrationsworkflowdrizzle-kit

More Drizzle ORM tasks

Back to the full Drizzle ORM cheat sheet