Deploy to Cloudflare Workers & Pages
Questions answered in this page
- How to deploy Prisma to Cloudflare Workers?
- Which drivers work on Workers/Pages?
- How to configure DATABASE_URL and envs?
General considerations when deploying to Cloudflare Workers
Section titled “General considerations when deploying to Cloudflare Workers”This section covers general things you need to be aware of when deploying to Cloudflare Workers or Pages and are using Prisma ORM, regardless of the database provider you use.
You can use Prisma Postgres and deploy to Cloudflare Workers.
After you create a Worker, run:
bunx --bun prisma@prev init --dbpnpm dlx prisma@prev init --dbyarn dlx prisma@prev init --dbnpx prisma@prev init --dbEnter a name for your project and choose a database region.
This command:
- Connects your CLI to your Prisma Data Platform account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.
- Creates a
prismadirectory containing aschema.prismafile for your database models. - Creates a
.envfile with yourDATABASE_URL.
When deploying a Cloudflare Worker that uses Prisma ORM, you need to use an edge-compatible driver and its respective driver adapter for Prisma ORM.
The edge-compatible drivers for Cloudflare Workers and Pages are:
- Neon Serverless uses HTTP to access the database
- PlanetScale Serverless uses HTTP to access the database
node-postgres(pg) uses Cloudflare'sconnect()(TCP) to access the database@libsql/clientis used to access Turso databases via HTTP- Cloudflare D1 is used to access D1 databases
There's also work being done on the node-mysql2 driver which will enable access to traditional MySQL databases from Cloudflare Workers and Pages in the future as well.
For hosted Prisma Postgres, use the Prisma Postgres serverless driver. For another database, choose a driver that supports Cloudflare Workers and use its Prisma driver adapter.
Setting your database connection URL as an environment variable
Section titled “Setting your database connection URL as an environment variable”First, ensure that your datasource block in your Prisma schema is configured correctly. Database connection URLs are configured in prisma.config.ts:
datasource db {
provider = "postgresql" // this might also be `mysql` or another value depending on your database
}import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});When using your Worker in development, you can configure your database connection via the .dev.vars file locally.
Assuming you use the DATABASE_URL environment variable from above, you can set it inside .dev.vars as follows:
DATABASE_URL="your-database-connection-string"In the above snippet, your-database-connection-string is a placeholder that you need to replace with the value of your own connection string, for example:
DATABASE_URL="postgresql://admin:mypassword42@somehost.aws.com:5432/mydb"Note that the .dev.vars file is not compatible with .env files which are typically used by Prisma ORM.
This means that you need to make sure that Prisma ORM gets access to the environment variable when needed, e.g. when running a Prisma CLI command like prisma migrate dev.
There are several options for achieving this:
-
Run your Prisma CLI commands using
dotenvto specify from where the CLI should read the environment variable, for example:dotenv -e .dev.vars -- npx prisma migrate dev -
Create a script in
package.jsonthat reads.dev.varsviadotenv. You can then executeprismacommands as follows:npm run env -- npx prisma migrate dev. Here's a reference for the script:title="package.json" "scripts": { "env": "dotenv -e .dev.vars" } -
Duplicate the
DATABASE_URLand any other relevant env vars into a new file called.envwhich can then be used by Prisma ORM.
When deploying your Worker to production, you'll need to set the database connection using the wrangler CLI:
bunx wrangler secret put DATABASE_URLpnpm dlx wrangler secret put DATABASE_URLyarn dlx wrangler secret put DATABASE_URLnpx wrangler secret put DATABASE_URLThe command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
[!NOTE] This command requires you to be authenticated, and will ask you to log in to your Cloudflare account in case you are not.
The command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
Cloudflare has a size limit of 3 MB for Workers on the free plan. If your application bundle with Prisma ORM exceeds that size, we recommend upgrading to a paid Worker plan.
Deploying a Next.js app to Cloudflare Pages with @cloudflare/next-on-pages
Section titled “Deploying a Next.js app to Cloudflare Pages with @cloudflare/next-on-pages”Cloudflare offers an option to run Next.js apps on Cloudflare Pages with @cloudflare/next-on-pages, see the Cloudflare Pages Next.js guide for instructions.
Based on some testing, we found the following:
- You can deploy using the PlanetScale or Neon Serverless Driver.
- Traditional PostgreSQL deployments using
pgdon't work becausepgitself currently does not work with@cloudflare/next-on-pages(seenext-on-pagesissue #605).
Feel free to reach out to us on Discord if you find that anything has changed about this.
Database-specific considerations & examples
Section titled “Database-specific considerations & examples”This section provides database-specific instructions for deploying a Cloudflare Worker with Prisma ORM.
As a prerequisite for the following section, you need to have a Cloudflare Worker running locally and the Prisma CLI installed.
If you don't have that yet, you can run these commands:
bunx create-cloudflare prisma-cloudflare-worker-example --type hello-world
cd prisma-cloudflare-worker-example
bun add prisma@prev --dev&& bun add @prisma/client@7
bunx --bun prisma init --output ../generated/prismapnpm create cloudflare prisma-cloudflare-worker-example --type hello-world
cd prisma-cloudflare-worker-example
pnpm add prisma@prev --save-dev&& pnpm add @prisma/client@7
pnpm prisma init --output ../generated/prismayarn create cloudflare prisma-cloudflare-worker-example --type hello-world
cd prisma-cloudflare-worker-example
yarn add prisma@prev --dev&& yarn add @prisma/client@7
yarn prisma init --output ../generated/prismanpm create cloudflare@latest prisma-cloudflare-worker-example -- --type hello-world
cd prisma-cloudflare-worker-example
npm install prisma@prev --save-dev && npm install @prisma/client@7
npx prisma init --output ../generated/prismaYou'll further need a database instance of your database provider of choice available. Refer to the respective documentation of the provider for setting up that instance.
We'll use the default User model for the example below:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}You'll further need a database instance of your database provider of choice available. Refer to the respective documentation of the provider for setting up that instance.
We'll use the default User model for the example below:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}If you are using a traditional PostgreSQL database that's accessed via TCP and the pg driver, you need to:
- use the
@prisma/adapter-pgdatabase adapter (learn more in Using driver adapters) - set
nodejs_compatinwrangler.jsonc(see the Cloudflare docs)
1. Configure Prisma schema & database connection
Section titled “1. Configure Prisma schema & database connection”First, ensure that the database connection is configured properly. Database connection URLs are configured in prisma.config.ts:
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});Next, you need to set the DATABASE_URL environment variable to the value of your database connection string. You'll do this in a file called .dev.vars used by Cloudflare:
DATABASE_URL="postgresql://admin:mypassword42@somehost.aws.com:5432/mydb"Because the Prisma CLI by default is only compatible with .env files, you can adjust your package.json with the following script that loads the env vars from .dev.vars. You can then use this script to load the env vars before executing a prisma command.
Add this script to your package.json:
{
// ...
"scripts": {
// ....
"env": "dotenv -e .dev.vars"
},
// ...
}Now you can execute Prisma CLI commands as follows while ensuring that the command has access to the env vars in .dev.vars:
bun run env npx prismapnpm run env npx prismayarn env npx prismanpm run env -- npx prismaNext, install the required packages:
bun add @prisma/adapter-pgpnpm add @prisma/adapter-pgyarn add @prisma/adapter-pgnpm install @prisma/adapter-pgIn your wrangler.jsonc file, add the following lines:
{
"compatibility_flags": [
"nodejs_compat"
],
"compatibility_date": "2026-08-23"
}4. Migrate your database schema (if applicable)
Section titled “4. Migrate your database schema (if applicable)”If you ran npx prisma init above, you need to migrate your database schema to create the User table that's defined in your Prisma schema (if you already have all the tables you need in your database, you can skip this step):
bun run env npx prisma migrate dev --name initpnpm run env npx prisma migrate dev --name inityarn env npx prisma migrate dev --name initnpm run env -- npx prisma migrate dev --name init5. Use Prisma Client in your Worker to send a query to the database
Section titled “5. Use Prisma Client in your Worker to send a query to the database”Here is a sample code snippet that you can use to instantiate PrismaClient and send a query to your database:
import { PrismaClient } from "./generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
export default {
async fetch(request, env, ctx) {
const adapter = new PrismaPg({ connectionString: env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
ctx.waitUntil(prisma.$disconnect());
return new Response(result);
},
};To run the Worker locally, you can run the wrangler dev command:
bunx wrangler devpnpm dlx wrangler devyarn dlx wrangler devnpx wrangler dev7. Set the DATABASE_URL environment variable and deploy the Worker
Section titled “7. Set the DATABASE_URL environment variable and deploy the Worker”To deploy the Worker, you first need to set the DATABASE_URL environment variable via the wrangler CLI:
bunx wrangler secret put DATABASE_URLpnpm dlx wrangler secret put DATABASE_URLyarn dlx wrangler secret put DATABASE_URLnpx wrangler secret put DATABASE_URLThe command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
[!NOTE] This command requires you to be authenticated, and will ask you to log in to your Cloudflare account in case you are not.
Then deploy the Worker:
The command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
Then deploy the Worker:
bunx wrangler deploypnpm dlx wrangler deployyarn dlx wrangler deploynpx wrangler deployThe command will output the URL where you can access the deployed Worker.
If you are using a PlanetScale database, you need to:
-
use the
@prisma/adapter-planetscaledatabase adapter (learn more in PlanetScale) -
manually remove the conflicting
cachefield:export default { async fetch(request, env, ctx) { const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL, // see https://github.com/cloudflare/workerd/issues/698 fetch(url, init) { delete init["cache"]; return fetch(url, init); }, }); const prisma = new PrismaClient({ adapter }); // ... }, };
1. Configure Prisma schema & database connection
Section titled “1. Configure Prisma schema & database connection”First, ensure that the database connection is configured properly. Database connection URLs are configured in prisma.config.ts:
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "mysql"
relationMode = "prisma" // required for PlanetScale (as by default foreign keys are disabled)
}import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});Next, you need to set the DATABASE_URL environment variable to the value of your database connection string. You'll do this in a file called .dev.vars used by Cloudflare:
DATABASE_URL="mysql://32qxa2r7hfl3102wrccj:password@us-east.connect.psdb.cloud/demo-cf-worker-ps?sslaccept=strict"Because the Prisma CLI by default is only compatible with .env files, you can adjust your package.json with the following script that loads the env vars from .dev.vars. You can then use this script to load the env vars before executing a prisma command.
Add this script to your package.json:
{
// ...
"scripts": {
// ....
"env": "dotenv -e .dev.vars"
},
// ...
}Now you can execute Prisma CLI commands as follows while ensuring that the command has access to the env vars in .dev.vars:
bun run env npx prismapnpm run env npx prismayarn env npx prismanpm run env -- npx prismaNext, install the required packages:
bun add @prisma/adapter-planetscalepnpm add @prisma/adapter-planetscaleyarn add @prisma/adapter-planetscalenpm install @prisma/adapter-planetscale3. Migrate your database schema (if applicable)
Section titled “3. Migrate your database schema (if applicable)”If you ran npx prisma init above, you need to migrate your database schema to create the User table that's defined in your Prisma schema (if you already have all the tables you need in your database, you can skip this step):
bun run env npx prisma db pushpnpm run env npx prisma db pushyarn env npx prisma db pushnpm run env -- npx prisma db push4. Use Prisma Client in your Worker to send a query to the database
Section titled “4. Use Prisma Client in your Worker to send a query to the database”Here is a sample code snippet that you can use to instantiate PrismaClient and send a query to your database:
import { PrismaClient } from "./generated/client";
import { PrismaPlanetScale } from "@prisma/adapter-planetscale";
export default {
async fetch(request, env, ctx) {
const adapter = new PrismaPlanetScale({
url: env.DATABASE_URL,
// see https://github.com/cloudflare/workerd/issues/698
fetch(url, init) {
delete init["cache"];
return fetch(url, init);
},
});
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
ctx.waitUntil(prisma.$disconnect());
return new Response(result);
},
};To run the Worker locally, you can run the wrangler dev command:
bunx wrangler devpnpm dlx wrangler devyarn dlx wrangler devnpx wrangler dev7. Set the DATABASE_URL environment variable and deploy the Worker
Section titled “7. Set the DATABASE_URL environment variable and deploy the Worker”To deploy the Worker, you first need to set the DATABASE_URL environment variable via the wrangler CLI:
bunx wrangler secret put DATABASE_URLpnpm dlx wrangler secret put DATABASE_URLyarn dlx wrangler secret put DATABASE_URLnpx wrangler secret put DATABASE_URLThe command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
[!NOTE] This command requires you to be authenticated, and will ask you to log in to your Cloudflare account in case you are not.
Then deploy the Worker:
The command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
Then deploy the Worker:
bunx wrangler deploypnpm dlx wrangler deployyarn dlx wrangler deploynpx wrangler deployThe command will output the URL where you can access the deployed Worker.
If you are using a Neon database, you need to:
- use the
@prisma/adapter-neondatabase adapter (learn more in Using driver adapters)
1. Configure Prisma schema & database connection
Section titled “1. Configure Prisma schema & database connection”First, ensure that the database connection is configured properly. Database connection URLs are configured in prisma.config.ts:
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});Next, you need to set the DATABASE_URL environment variable to the value of your database connection string. You'll do this in a file called .dev.vars used by Cloudflare:
DATABASE_URL="postgresql://janedoe:password@ep-nameless-pond-a23b1mdz.eu-central-1.aws.neon.tech/neondb?sslmode=require"Because the Prisma CLI by default is only compatible with .env files, you can adjust your package.json with the following script that loads the env vars from .dev.vars. You can then use this script to load the env vars before executing a prisma command.
Add this script to your package.json:
{
// ...
"scripts": {
// ....
"env": "dotenv -e .dev.vars"
},
// ...
}Now you can execute Prisma CLI commands as follows while ensuring that the command has access to the env vars in .dev.vars:
bun run env npx prismapnpm run env npx prismayarn env npx prismanpm run env -- npx prismaNext, install the required packages:
bun add @prisma/adapter-neonpnpm add @prisma/adapter-neonyarn add @prisma/adapter-neonnpm install @prisma/adapter-neon3. Migrate your database schema (if applicable)
Section titled “3. Migrate your database schema (if applicable)”If you ran npx prisma init above, you need to migrate your database schema to create the User table that's defined in your Prisma schema (if you already have all the tables you need in your database, you can skip this step):
bun run env npx prisma migrate dev --name initpnpm run env npx prisma migrate dev --name inityarn env npx prisma migrate dev --name initnpm run env -- npx prisma migrate dev --name init5. Use Prisma Client in your Worker to send a query to the database
Section titled “5. Use Prisma Client in your Worker to send a query to the database”Here is a sample code snippet that you can use to instantiate PrismaClient and send a query to your database:
import { PrismaClient } from "./generated/client";
import { PrismaNeon } from "@prisma/adapter-neon";
export default {
async fetch(request, env, ctx) {
const adapter = new PrismaNeon({ connectionString: env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
ctx.waitUntil(prisma.$disconnect());
return new Response(result);
},
};To run the Worker locally, you can run the wrangler dev command:
bunx wrangler devpnpm dlx wrangler devyarn dlx wrangler devnpx wrangler dev7. Set the DATABASE_URL environment variable and deploy the Worker
Section titled “7. Set the DATABASE_URL environment variable and deploy the Worker”To deploy the Worker, you first need to set the DATABASE_URL environment variable via the wrangler CLI:
bunx wrangler secret put DATABASE_URLpnpm dlx wrangler secret put DATABASE_URLyarn dlx wrangler secret put DATABASE_URLnpx wrangler secret put DATABASE_URLThe command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
[!NOTE] This command requires you to be authenticated, and will ask you to log in to your Cloudflare account in case you are not.
Then deploy the Worker:
The command is interactive and will ask you to enter the value for the DATABASE_URL env var as the next step in the terminal.
Then deploy the Worker:
bunx wrangler deploypnpm dlx wrangler deployyarn dlx wrangler deploynpx wrangler deployThe command will output the URL where you can access the deployed Worker.