Next.js, Prisma, PlanetScale and Vercel
Deploy your Next.js + Prisma app to PlanetScale and Vercel
Concepts
First, let's go over the main concepts of Prisma and PlanetScale.
- Prisma Migrate: Takes your schema changes and applies them to your database.
- PlanetScale Branches: Just like
git
branches: with amain
(production) branch and development branches. Schema changes cannot be made directly on themain
branch. - PlanetScale Deploy Request: Like
git
pull requests but for development branches againts the production branch. You don't make schema changes on yourmain
branch. You use deploy requests. - Shadow Database: A temporary database used by
prisma migrate
to protect and detect manual changes (schema drift) on the development database.
Branches and Deploy Requests
Here's how it works:
When you first deploy your app to Vercel, Prisma will try to run prisma migrate
against your connected database on the production branch.
Since schema changes cannot be made to the production branch, you will see the following error:
16:09:50.549 Error: P3018
16:09:50.550 Direct execution of DDL (Data Definition Language) SQL statements is disabled on this database. Please read more here how to handle this: https://pris.ly/d/migrate-no-direct-ddl
To fix this:
- We are going to run
prisma migrate
on a development branch. - Then we'll create a deploy request againts the
main
branch. - We'll merge the deploy request to apply the schema changes.

Prerequisites
- Turn on Automatically copy migration data on your database Settings page on PlanetScale.
- Install the PlanetScale CLI

Workflow
The following commands and code changes are done on your local machine from the root of your Next.js app.
Update schema.prisma
Update your schema.prisma
file and enable referentialIntegrity
(previously called planetScaleMode
- thanks @brian_lovin).
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
+ shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
+ referentialIntegrity = "prisma"
}
generator client {
provider = "prisma-client-js"
+ previewFeatures = ["referentialIntegrity"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
+ shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
+ referentialIntegrity = "prisma"
}
generator client {
provider = "prisma-client-js"
+ previewFeatures = ["referentialIntegrity"]
}
Commit and push these schema.prisma
changes.
Apply schema changes
- Login to PlanetScale
pscale auth login
pscale auth login
- Create two development branches (one to run the initial migrations and one as a shadow branch).
pscale branch create NAME-OF-YOUR-DATABASE init
pscale branch create NAME-OF-YOUR-DATABASE shadow
pscale branch create NAME-OF-YOUR-DATABASE init
pscale branch create NAME-OF-YOUR-DATABASE shadow
- Update your
.env
file and add the following (If you already have a localDATABASE_URL
configured, you can temporarily comment it out):
DATABASE_URL="mysql://root@127.0.0.1:3309/NAME-OF-YOUR-DATABASE"
SHADOW_DATABASE_URL="mysql://root@127.0.0.1:3310/NAME-OF-YOUR-DATABASE"
DATABASE_URL="mysql://root@127.0.0.1:3309/NAME-OF-YOUR-DATABASE"
SHADOW_DATABASE_URL="mysql://root@127.0.0.1:3310/NAME-OF-YOUR-DATABASE"
- Connect to the
init
branch.
pscale connect NAME-OF-YOUR-DATABASE init --port 3309
pscale connect NAME-OF-YOUR-DATABASE init --port 3309
- In another terminal, connect to the
shadow
branch.
pscale connect NAME-OF-YOUR-DATABASE shadow --port 3310
pscale connect NAME-OF-YOUR-DATABASE shadow --port 3310
- Run the migrations.
yarn prisma migrate dev
yarn prisma migrate dev
Create deploy request.
The init
branch now has your initial schema. To apply this schema to the main
branch, we'll create a deploy request.
- Create a deploy request:
pscale deploy-request create NAME-OF-YOUR-DATABASE init
pscale deploy-request create NAME-OF-YOUR-DATABASE init
Once the deploy request is created you can visit your PlanelScale dashboard to see the request and the schema changes.
- Merge the deploy request:
pscale deploy-request deploy NAME-OF-YOUR-DATABASE DEPLOY-REQUEST-NUMBER
pscale deploy-request deploy NAME-OF-YOUR-DATABASE DEPLOY-REQUEST-NUMBER
Since this is your first deploy request, the DEPLOY-REQUEST-NUMBER
is 1.
You have now successfully deploy the initial schema to your main
branch.
You may safely remove the DATABASE_URL
and SHADOW_DATABASE_URL
from your .env
file and delete the development branches.
pscale branch delete NAME-OF-YOUR-DATABASE init
pscale branch delete NAME-OF-YOUR-DATABASE shadow
pscale branch delete NAME-OF-YOUR-DATABASE init
pscale branch delete NAME-OF-YOUR-DATABASE shadow
Deploy to Vercel
Now that your database is ready, you can deploy your Next.js app to Vercel.
PlanelScale Integration
Enable the PlanelScale integration from your Vercel dashboard under Integrations.
Connect database

- Visit your PlanetScale database page.
- Click on Connect.
- Select Prisma under Format.
- Copy the
url
. - Replace
sslcert=/etc/ssl/cert.pem
withsslcert=/etc/pki/tls/certs/ca-bundle.crt
. - Add this
url
as an environment variable namedDATABASE_URL
on Vercel.
Deploy
You are now ready to deploy.
vercel deploy --prod
vercel deploy --prod
#vercelconfetti 🎉