Prisma ORM and [PlanetScale](https://planetscale.com/) together provide a development arena that optimizes rapid, type-safe development of data access applications, using Prisma's ORM and PlanetScale's highly scalable MySQL-based platform powered by Vitess.

:::note

This guide covers **PlanetScale MySQL** (powered by Vitess). If you're using **PlanetScale Postgres**, see the [PlanetScale Postgres guide](/orm/overview/databases/planetscale-postgres) instead.

:::

This document discusses the concepts behind using Prisma ORM and PlanetScale, explains the commonalities and differences between PlanetScale and other database providers, and leads you through the process for configuring your application to integrate with PlanetScale.

## What is PlanetScale?

PlanetScale uses the [Vitess](https://vitess.io/) database clustering system to provide a MySQL-compatible database platform. Features include:

- **Enterprise scalability.** PlanetScale provides a highly available production database cluster that supports scaling across multiple database servers. This is particularly useful in a serverless context, as it avoids the problem of having to [manage connection limits](/orm/prisma-client/setup-and-configuration/databases-connections#serverless-environments-faas).
- **Database branches.** PlanetScale allows you to create [branches of your database schema](https://planetscale.com/docs/concepts/branching), so that you can test changes on a development branch before applying them to your production database.
- **Support for [non-blocking schema changes](https://planetscale.com/docs/concepts/nonblocking-schema-changes).** PlanetScale provides a workflow that allows users to update database schemas without locking the database or causing downtime.

## Commonalities with other database providers

Many aspects of using Prisma ORM with PlanetScale are just like using Prisma ORM with any other relational database. You can still:

- model your database with the [Prisma Schema Language](/orm/prisma-schema)
- use Prisma ORM's existing [`mysql` database connector](/orm/overview/databases/mysql) in your schema, along with the [connection string PlanetScale provides you](https://planetscale.com/docs/concepts/connection-strings)
- use [Introspection](/orm/prisma-schema/introspection) for existing projects if you already have a database schema in PlanetScale
- use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) to push changes in your schema to the database
- use [Prisma Client](/orm/prisma-client) in your application to talk to the database server at PlanetScale

## Differences to consider

PlanetScale's branching model and design for scalability means that there are also a number of differences to consider. You should be aware of the following points when deciding to use PlanetScale with Prisma ORM:

- **Branching and deploy requests.** PlanetScale provides two types of database branches: _development branches_, which allow you to test out schema changes, and _production branches_, which are protected from direct schema changes. Instead, changes must be first created on a development branch and then deployed to production using a deploy request. Production branches are highly available and include automated daily backups. To learn more, see [How to use branches and deploy requests](#how-to-use-branches-and-deploy-requests).
- **Referential actions and integrity.** To support scaling across multiple database servers, PlanetScale [by default does not use foreign key constraints](https://planetscale.com/docs/learn/operating-without-foreign-key-constraints), which are normally used in relational databases to enforce relationships between data in different tables, and asks users to handle this manually in their applications. However, you can explicitly [enable them in the PlanetScale database settings](https://planetscale.com/docs/concepts/foreign-key-constraints). If you don't enable these explicitly, you can still maintain these relationships in your data and allow the use of [referential actions](/orm/prisma-schema/data-model/relations/referential-actions) by using Prisma ORM's ability to [emulate relations in Prisma Client](/orm/prisma-schema/data-model/relations/relation-mode#emulate-relations-in-prisma-orm-with-the-prisma-relation-mode) with the `prisma` relation mode. For more information, see [How to emulate relations in Prisma Client](#option-1-emulate-relations-in-prisma-client).
- **Creating indexes on foreign keys.** When [emulating relations in Prisma ORM](#option-1-emulate-relations-in-prisma-client) (i.e. when _not_ using foreign key constraints on the database-level), you will need to create dedicated indexes on foreign keys. In a standard MySQL database, if a table has a column with a foreign key constraint, an index is automatically created on that column. When PlanetScale is configured to not use foreign key constraints, these indexes are [currently](https://github.com/prisma/prisma/issues/10611) not created when Prisma Client emulates relations, which can lead to issues with queries not being well optimized. To avoid this, you can create indexes in Prisma ORM. For more information, see [How to create indexes on foreign keys](#2-create-indexes-on-foreign-keys).
- **Making schema changes with `db push`.** When you merge a development branch into your production branch, PlanetScale will automatically compare the two schemas and generate its own schema diff. This means that Prisma ORM's [`prisma migrate`](/orm/prisma-migrate) workflow, which generates its own history of migration files, is not a natural fit when working with PlanetScale. These migration files may not reflect the actual schema changes run by PlanetScale when the branch is merged.

  :::warning

  We recommend not using `prisma migrate` when making schema changes with PlanetScale. Instead, we recommend that you use the `prisma db push` command.

  :::

  For an example of how this works, see [How to make schema changes with `db push`](#how-to-make-schema-changes-with-db-push)

- **Introspection**. When you introspect on an existing database and you have _not_ enabled [foreign key constraints in your PlanetScale database](#option-2-enable-foreign-key-constraints-in-the-planetscale-database-settings), you will get a schema with no relations, as they are usually defined based on foreign keys that connect tables. In that case, you will need to add the missing relations in manually. For more information, see [How to add in missing relations after Introspection](#how-to-add-in-missing-relations-after-introspection).

## How to use branches and deploy requests

When connecting to PlanetScale with Prisma ORM, you will need to use the correct connection string for your branch. The connection URL for a given database branch can be found from your PlanetScale account by going to the overview page for the branch and selecting the 'Connect' dropdown. In the 'Passwords' section, generate a new password and select 'Prisma' from the dropdown to get the Prisma format for the connection URL. See Prisma ORM's [Getting started guide](/getting-started/prisma-orm/quickstart/planetscale) for more details of how to connect to a PlanetScale database.

Every PlanetScale database is created with a branch called `main`, which is initially a development branch that you can use to test schema changes on. Once you are happy with the changes you make there, you can [promote it](https://planetscale.com/docs/concepts/branching#promote-a-branch-to-production) to become a production branch. Note that you can only push new changes to a development branch, so further changes will need to be created on a separate development branch and then later deployed to production using a [deploy request](https://planetscale.com/docs/concepts/branching#promote-a-branch-to-production).

If you try to push to a production branch, you will get the [error message](/orm/reference/error-reference#p3022) `Direct execution of DDL (Data Definition Language) SQL statements is disabled on this database.`

## How to use relations (and enable referential integrity) with PlanetScale

### Option 1: Emulate relations in Prisma Client

#### 1. Set `relationMode = "prisma"`

PlanetScale does not use foreign key constraints in its database schema by default. However, Prisma ORM relies on foreign key constraints in the underlying database to enforce referential integrity between models in your Prisma schema.

In Prisma ORM versions 3.1.1 and later, you can [emulate relations in Prisma Client with the `prisma` relation mode](/orm/prisma-schema/data-model/relations/relation-mode#emulate-relations-in-prisma-orm-with-the-prisma-relation-mode), which avoids the need for foreign key constraints in the database.

To enable emulation of relations in Prisma Client, set the `relationMode` field to `"prisma"` in the `datasource` block:

```prisma file=schema.prisma
datasource db {
  provider     = "mysql"
  relationMode = "prisma"
}
```

:::info

The ability to set the relation mode was introduced as part of the `referentialIntegrity` preview feature in Prisma ORM version 3.1.1, and is generally available in Prisma ORM versions 4.8.0 and later.<br /><br />The `relationMode` field was renamed in Prisma ORM version 4.5.0, and was previously named `referentialIntegrity`.

:::

If you use relations in your Prisma schema with the default `"foreignKeys"` option for the `relationMode` field, PlanetScale will error and Prisma ORM output the [P3021 error message](/orm/reference/error-reference#p3021) when it tries to create foreign keys. (In versions before 2.27.0 it will output a raw database error.)

#### 2. Create indexes on foreign keys

When [you emulate relations in Prisma Client](#option-1-emulate-relations-in-prisma-client), you need to create your own indexes. As an example of a situation where you would want to add an index, take this schema for a blog with posts and comments:

```prisma file=schema.prisma
model Post {
  id       Int       @id @default(autoincrement())
  title    String
  content  String
  likes    Int       @default(0)
  comments Comment[]
}

model Comment {
  id      Int    @id @default(autoincrement())
  comment String
  postId  Int
  post    Post   @relation(fields: [postId], references: [id], onDelete: Cascade)
}
```

The `postId` field in the `Comment` model refers to the corresponding `id` field in the `Post` model. However this is not implemented as a foreign key in PlanetScale, so the column doesn't have an automatic index. This means that some queries may not be well optimized. For example, if you query for all comments with a certain post `id`, PlanetScale may have to do a full table lookup. This could be slow, and also expensive because PlanetScale's billing model charges for the number of rows read.

To avoid this, you can define an index on the `postId` field using [Prisma ORM's `@@index` argument](/orm/reference/prisma-schema-reference#index):

```prisma file=schema.prisma highlight=15;add
model Post {
  id       Int       @id @default(autoincrement())
  title    String
  content  String
  likes    Int       @default(0)
  comments Comment[]
}

model Comment {
  id      Int    @id @default(autoincrement())
  comment String
  postId  Int
  post    Post   @relation(fields: [postId], references: [id], onDelete: Cascade)

  //add-next-line
  @@index([postId])
}
```

You can then add this change to your schema [using `db push`](#how-to-make-schema-changes-with-db-push).

In versions 4.7.0 and later, Prisma ORM warns you if you have a relation with no index on the relation scalar field. For more information, see [Index validation](/orm/prisma-schema/data-model/relations/relation-mode#index-validation).

:::warning

One issue to be aware of is that [implicit many-to-many relations](/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) cannot have an index added in this way. If query speed or cost is an issue, you may instead want to use an [explicit many-to-many relation](/orm/prisma-schema/data-model/relations/many-to-many-relations#explicit-many-to-many-relations) in this case.

:::

### Option 2: Enable foreign key constraints in the PlanetScale database settings

Support for foreign key constraints in PlanetScale databases has been Generally Available since February 2024. Follow the instructions in the [PlanetScale documentation](https://planetscale.com/docs/concepts/foreign-key-constraints) to enable them in your database.

You can then use Prisma ORM and define relations in your Prisma schema without the need for extra configuration.

In that case, you can define a relation as with other database that supports foreign key constraints, for example:

```prisma file=schema.prisma
model Post {
  id       Int       @id @default(autoincrement())
  title    String
  content  String
  likes    Int       @default(0)
  comments Comment[]
}

model Comment {
  id      Int    @id @default(autoincrement())
  comment String
  postId  Int
  post    Post   @relation(fields: [postId], references: [id], onDelete: Cascade)
}
```

With this approach, it is _not_ necessary to:

- set `relationMode = "prisma"` in your Prisma schema
- define additional indexes on foreign keys

Also, introspection will automatically create relation fields in your Prisma schema because it can detect the foreign key constraints in the database.

## How to make schema changes with `db push`

To use `db push` with PlanetScale, you will first need to [enable emulation of relations in Prisma Client](#option-1-emulate-relations-in-prisma-client). Pushing to your branch without referential emulation enabled will give the [error message](/orm/reference/error-reference#p3021) `Foreign keys cannot be created on this database.`

As an example, let's say you decide to decide to add a new `excerpt` field to the blog post schema above. You will first need to [create a new development branch and connect to it](#how-to-use-branches-and-deploy-requests).

Next, add the following to your `schema.prisma` file:

```prisma file=schema.prisma highlight=5;edit
model Post {
  id       Int       @id @default(autoincrement())
  title    String
  content  String
  //edit-next-line
  excerpt  String?
  likes    Int       @default(0)
  comments Comment[]
}

model Comment {
  id      Int    @id @default(autoincrement())
  comment String
  postId  Int
  post    Post   @relation(fields: [postId], references: [id], onDelete: Cascade)

  @@index([postId])
}
```

To push these changes, navigate to your project directory in your terminal and run

```terminal
npx prisma db push
```

Once you are happy with your changes on your development branch, you can open a deploy request to deploy these to your production branch.

For more examples, see PlanetScale's tutorial on [automatic migrations with Prisma ORM](https://planetscale.com/docs/prisma/automatic-prisma-migrations) using `db push`.

## How to add in missing relations after introspection

> **Note**: This section is only relevant if you use `relationMode = "prisma"` to emulate foreign key constraints with Prisma ORM. If you enabled foreign key constraints in your PlanetScale database, you can ignore this section.

After introspecting with `npx prisma db pull`, the schema you get may be missing some relations. For example, the following schema is missing a relation between the `User` and `Post` models:

```prisma file=schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  title     String   @db.VarChar(255)
  content   String?
  authorId  Int

  @@index([authorId])
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}
```

In this case you need to add the relation in manually:

```prisma file=schema.prisma highlight=6,16;add
model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  title     String   @db.VarChar(255)
  content   String?
  //add-next-line
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int

  @@index([authorId])
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  //add-next-line
  posts Post[]
}
```

For a more detailed example, see the [Getting started guide for PlanetScale](/getting-started/prisma-orm/add-to-existing-project/planetscale).

## How to define shard keys in your Prisma schema (Preview)

[Sharding](https://planetscale.com/docs/vitess/sharding) is a popular technique to scale up when database load grows. 

As of [v6.10.0](https://github.com/prisma/prisma/releases/tag/6.10.0), Prisma ORM supports sharding on PlanetScale natively (as a [Preview](/orm/more/releases#preview) feature) via the [`@shardKey`](/orm/reference/prisma-schema-reference#shardkey) and [`@@shardKey`](/orm/reference/prisma-schema-reference#shardkey-1) attributes in the Prisma schema which you can apply to the fields in your models that should serve as shard keys in your database setup.

In order to use the shard key attributes, you need to specify the `shardKeys` Preview feature on your `generator`:

```prisma
generator client {
  provider = "prisma-client"
  output = "./generated/prisma"
  previewFeatures = ["shardKeys"]
}
```

Now you can use the `@shardKey` and `@@shardKey` attributes:

**Single-column shard key**

```prisma
model User {
  id     String @default(uuid())
  region String @shardKey
}
```

**Multi-column shard key**

```prisma
model User {
  id         String @default(uuid())
  country    String
  customerId String
  @@shardKey([country, customerId])
}
```

## How to use the PlanetScale serverless driver with Prisma ORM (Preview)

The [PlanetScale serverless driver](https://planetscale.com/docs/tutorials/planetscale-serverless-driver) provides a way of communicating with your database and executing queries over HTTP.

You can use Prisma ORM along with the PlanetScale serverless driver using the [`@prisma/adapter-planetscale`](https://www.npmjs.com/package/@prisma/adapter-planetscale) driver adapter. The driver adapter allows you to communicate with your database over HTTP.

:::info

This feature has been Generally Available since Prisma ORM [v6.16.0](https://pris.ly/release/6.16.0).

:::


:::info

Ensure you update the host value in your connection string to `aws.connect.psdb.cloud`. You can learn more about this [here](https://planetscale.com/docs/tutorials/planetscale-serverless-driver#add-and-use-the-planetscale-serverless-driver-for-javascript-to-your-project).

```bash
DATABASE_URL='mysql://johndoe:strongpassword@aws.connect.psdb.cloud/clear_nightsky?sslaccept=strict'
```

:::

Install the Prisma ORM adapter for PlanetScale, PlanetScale serverless driver and `undici` packages:

```terminal
npm install @prisma/adapter-planetscale undici
```

:::info

When using a Node.js version below 18, you must provide a custom fetch function implementation. We recommend the `undici` package on which Node's built-in fetch is based. Node.js versions 18 and later include a built-in global `fetch` function, so you don't have to install an extra package.

:::

Update your Prisma Client instance to use the PlanetScale serverless driver:

```ts
import { PrismaPlanetScale } from '@prisma/adapter-planetscale'
import { PrismaClient } from './generated/prisma/client'
import dotenv from 'dotenv'
import { fetch as undiciFetch } from 'undici'

dotenv.config()
const connectionString = `${process.env.DATABASE_URL}`

const adapter = new PrismaPlanetScale({ url: connectionString, fetch: undiciFetch })
const prisma = new PrismaClient({ adapter })
```

You can then use Prisma Client as you normally would with full type-safety. Prisma Migrate, introspection, and Prisma Studio will continue working as before using the connection string defined in the Prisma schema.

## More on using PlanetScale with Prisma ORM

The fastest way to start using PlanetScale with Prisma ORM is to refer to our Getting Started documentation:

- [Start from scratch](/getting-started/prisma-orm/quickstart/planetscale)
- [Add to existing project](/getting-started/prisma-orm/add-to-existing-project/planetscale)

These tutorials will take you through the process of connecting to PlanetScale, pushing schema changes, and using Prisma Client.

For further tips on best practices when using Prisma ORM and PlanetScale together, watch our video:

<div class="videoWrapper">

<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/iaHt5_hg44c"
  frameborder="0"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
></iframe>

</div>

---

# PlanetScale Postgres