orm-guidesby September 8, 202610 min read1,982 words

Prisma db pull vs db push vs migrate dev vs migrate deploy

A practical Prisma 7 guide to db pull, db push, migrate dev, and migrate deploy: which direction data flows, whether migrations are created, where drift is checked, and which command belongs in production.

prisma db pull vs db pushprisma migrate dev vs db pushprisma migrate deploy vs migrate devprisma schema driftprisma db pull
ShareXLinkedInHN

Prisma has four commands that look deceptively similar because all of them touch your schema. They do very different jobs.

The shortest mental model is:

CommandDirectionCreates migration files?Checks drift?Best use
prisma db pullDatabase → schema.prismaNoNo migration-history checkIntrospect an existing database or bring manual DB changes back into code
prisma db pushschema.prisma → databaseNoCompares desired schema to DB to synchronize itFast local prototyping when migration history does not matter
prisma migrate devSchema + migration history → development DBYesYes, in development, with a shadow databaseNormal migration workflow while developing
prisma migrate deployExisting migration files → staging/production DBNo new filesNo production drift checkApply already-reviewed migrations in deployment

That last column is the part worth remembering. pull is database-first. push is state synchronization without migration history. migrate dev creates and validates migration history in development. migrate deploy applies that history in production.

prisma db pull: the database is the source of truth

prisma db pull introspects the connected database and writes the result into your Prisma schema.

npx prisma db pull

Use it when the database already exists and you want Prisma to learn its current structure. A common example is joining an existing project, connecting Prisma to a database created by another framework, or bringing an intentional manual database change back into schema.prisma.

The important direction is:

live database
     │
     ▼
schema.prisma

Current Prisma 7 documentation warns that db pull rewrites the current schema based on introspection and recommends backing it up or committing it first if it contains important modifications. Relational introspection preserves several Prisma-level customizations, such as mapping attributes and comments, but you should still treat the command as a write to schema.prisma, not as a read-only inspection.

If you only want to see what Prisma would produce, use:

npx prisma db pull --print

That prints the introspected schema instead of writing it to the file.

When db pull is the right command

  • A DBA or migration outside Prisma intentionally changed the database and you want to reflect that change in Prisma.
  • You are adopting Prisma on an existing database.
  • You need a fresh view of what Prisma can introspect from the live database.
  • You want to inspect first with --print before modifying the schema file.

What db pull does not do

It does not create a migration that explains how the database reached its current state. If you are maintaining Prisma migration history, introspection is only one step. You still need to decide how the newly introspected state should be represented in that history.

Prisma's own troubleshooting guide describes this workflow for manual database changes you want to keep: run db pull, then create a migration so the change is represented in your migration history.

prisma db push: make the database match the schema, without migrations

prisma db push goes in the opposite direction.

npx prisma db push

Prisma introspects the database, calculates the changes required to make it match schema.prisma, and executes those changes directly. It does not create migration files and does not update _prisma_migrations.

schema.prisma
     │
     ▼
live database

no migration file in between

This is why Prisma recommends db push for rapid prototyping and local development where you care about the final schema state more than the exact migration steps used to get there.

If a proposed change can cause data loss, Prisma stops and requires explicit acceptance before proceeding:

npx prisma db push --accept-data-loss

That flag is not a production strategy. It is a signal that you are accepting the destructive schema operation db push calculated.

Also note a Prisma 7 change: db push no longer automatically runs prisma generate. Run generation separately when you need an updated client.

When db push is the right command

  • You are sketching a schema locally and do not care about migration history yet.
  • You are building a disposable prototype or test database.
  • You need the database to reach the current Prisma schema state quickly.
  • You use MongoDB, where Prisma Migrate is not the workflow and db push is used instead.

When db push becomes dangerous as a habit

Once multiple developers, staging, and production need to reproduce the same sequence of changes, migration history matters. db push gives you the end state but not a versioned artifact that can be reviewed, committed, and replayed elsewhere.

Prisma's documentation explicitly recommends moving to migrations when you need repeatable changes across environments, fine-grained control over data migrations, or a history of schema changes.

prisma migrate dev: create migrations and detect development drift

For a normal Prisma migration workflow during development, this is the central command:

npx prisma migrate dev --name add_order_status

migrate dev does more than generate SQL from schema.prisma.

According to Prisma's current documentation, it:

  1. Replays the existing migration history in a shadow database.
  2. Uses that replay to detect whether the development database has drifted away from the migration-history end state.
  3. Applies pending migrations to the shadow database.
  4. Generates a new migration from your Prisma schema changes.
  5. Applies unapplied migrations to the development database.

That gives it an important property neither db pull nor a simple production deploy has: it reasons about migration history and the current development database together.

If you want to inspect the generated migration before applying it, use:

npx prisma migrate dev --create-only --name add_order_status

You can then review or customize the SQL before applying it. Prisma documents this as the path for changes that need custom SQL, such as preserving data during a schema transformation.

migrate dev is development-only

The command can ask to reset a database when migration history conflicts or drift are detected. That behavior makes sense against a disposable development database and is exactly why Prisma says not to run migrate dev in production.

Prisma 7 also changed generation behavior: migrate dev no longer automatically triggers prisma generate or seed scripts. Run those explicitly when your workflow requires them.

prisma migrate deploy: apply reviewed migrations, and nothing more

Production is different:

npx prisma migrate deploy

migrate deploy applies pending migration files. It is designed for staging and production and works well in CI/CD because it is non-interactive and does not try to redesign the schema on the fly.

The subtle part is what it does not do.

Prisma's current documentation explicitly states that migrate deploy:

  • does not look for drift in the database;
  • does not look for changes in schema.prisma;
  • does not use a shadow database;
  • does not generate migration artifacts.

That is not a bug. It is a deliberate production safety boundary: deploy the migration files that were reviewed and committed, rather than inventing schema changes while deploying.

It also means this is possible:

migrations/ say state A
schema.prisma says state A
production DB was manually changed to state B

prisma migrate deploy
        │
        └── applies pending migrations
            but does not first prove B == A

This distinction is easy to miss if you assume “Prisma has drift detection” means every Prisma migration command checks every environment. It does not. migrate dev performs development drift detection; migrate deploy intentionally does not perform a production drift check.

That environment boundary is one reason I built QueryDeck's schema-drift view: it compares the ORM schema you are working with against the database you are actually connected to without making migration application the moment you discover the difference.

The decision tree

Use this instead of memorizing command names.

“The database changed and code needs to learn about it”

Use:

npx prisma db pull

If the manual database change should become part of Prisma migration history, follow the introspection with an appropriate migration workflow.

“I changed schema.prisma and I just want my local DB to match”

For a disposable prototype where history does not matter:

npx prisma db push

For a project where schema changes must be versioned:

npx prisma migrate dev --name describe_the_change

“I need to create SQL but review it before it runs”

Use:

npx prisma migrate dev --create-only --name describe_the_change

Review the generated migration, customize it if needed, then apply it through the normal development flow.

“CI is deploying an already-reviewed migration to production”

Use:

npx prisma migrate deploy

Do not substitute migrate dev or db push for the production migration step.

“I only want to compare two schema states”

That is where prisma migrate diff fits. It is the diagnostic comparison command and can compare arbitrary supported sources. It is separate from migrate deploy, which applies migrations but does not perform a production drift check first.

A practical team workflow

For a conventional Prisma project with PostgreSQL or MySQL, a clean workflow looks like this:

1. Edit schema.prisma locally
2. prisma migrate dev --create-only --name ...
3. Review the generated SQL
4. prisma migrate dev
5. Commit schema.prisma + migration files
6. CI tests the application
7. Deployment runs prisma migrate deploy
8. Independently verify that the live DB still matches the intended schema

Step 8 matters because production deploy is intentionally not a drift detector. A manual hotfix, an external migration tool, or an environment-specific change can make the database diverge without changing the migration files in Git.

If you use QueryDeck, Drift Mode is designed for that last comparison: project schema on one side, the connected live database on the other. It does not replace Prisma Migrate; it gives you a separate place to inspect the state before deciding which side should change.

Common mistakes

Using db pull because you are afraid of losing the database

db pull is not a “safe version of db push.” It changes the other side. It rewrites your Prisma schema from the database state. If code is supposed to be the source of truth, pulling blindly can move you in the wrong direction.

Using db push on a team project forever

It feels convenient because there are no migration files to manage. That convenience becomes a problem when another environment needs to reproduce the same schema change safely and reviewably.

Assuming migrate deploy validates production drift

It does not. Prisma says so directly in the CLI documentation. Its job is to apply pending migrations, not to reconcile arbitrary production state.

Running migrate dev in production to get drift detection

Do not do this. Prisma marks migrate dev as development-only. The correct response to the production drift gap is a separate verification step, not using a development migration command against production.

Sources

If the part you care about is not command selection but how to see whether the ORM and live database disagree right now, read the schema drift deep dive. For the broader ORM trade-off, see Drizzle vs Prisma in 2026.

ShareXLinkedInHN
Related articles

Try QueryDeck free for 14 days.

Launch offer: Lifetime at $79 for the first 10 customers, then $149. Try it free for 14 days, no card required.

Launch offerLifetime at $79 for the first 10 customers, then $149.Try free for 14 days