Skip to main content
Prisma Documentation Docs

Search documentation

Type to search this documentation.

On this pageOverview

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?

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.

Use the Prisma Postgres serverless driver to connect from a Cloudflare Worker over HTTP and WebSockets. This path requires Prisma ORM 6.19 or later.

Configure an engine-less Prisma Client:

title="prisma/schema.prisma"
generator client {

  provider   = "prisma-client"

  output     = "../generated/client"

  engineType = "client"

  runtime    = "workerd"

}

datasource db {

  provider = "postgresql"

  url      = env("DATABASE_URL")

}

Install the Prisma Postgres adapter and driver:

Bash
bun add @prisma/adapter-ppg @prisma/ppg
Terminal
pnpm add @prisma/adapter-ppg @prisma/ppg
Terminal
yarn add @prisma/adapter-ppg @prisma/ppg
Terminal
npm install @prisma/adapter-ppg @prisma/ppg

In the Prisma Console, select your database, choose Connect to your database, generate a connection string, and store the direct value in the Worker's DATABASE_URL secret. The serverless driver accepts the direct connection-string format as a credential but communicates over HTTP and WebSockets rather than TCP.

Instantiate Prisma Client with PrismaPostgresAdapter:

src/index.ts
import { PrismaPostgresAdapter } from "@prisma/adapter-ppg";
import { PrismaClient } from "../generated/client/client";

export interface Env {
  DATABASE_URL: string;
}

export default {
  async fetch(request, env, ctx) {
    const adapter = new PrismaPostgresAdapter({
      connectionString: env.DATABASE_URL,
    });
    const prisma = new PrismaClient({ adapter });

    const users = await prisma.user.findMany();
    const result = JSON.stringify(users);
    return new Response(result);
  },
} satisfies ExportedHandler<Env>;

Generate Prisma Client and configure the development and production secrets as shown in this section. Keep database credentials in Worker secrets and never include them in browser-delivered code.

[!NOTE] You need to have the dotenv-cli package installed as Cloudflare Workers does not support .env files. You can do this by running the following command to install the package locally in your project: npm install -D dotenv-cli.

In the Prisma Console, select your database, choose Connect to your database, generate a connection string, and store the direct value in the Worker's DATABASE_URL secret. The serverless driver accepts the direct connection-string format as a credential but communicates over HTTP and WebSockets rather than TCP.

Instantiate Prisma Client with PrismaPostgresAdapter:

title="src/index.ts"
import { PrismaPostgresAdapter } from "@prisma/adapter-ppg";

import { PrismaClient } from "../generated/client/client";

export interface Env {

  DATABASE_URL: string;

}

export default {

  async fetch(request, env, ctx) {

    const adapter = new PrismaPostgresAdapter({

      connectionString: env.DATABASE_URL,

    });

    const prisma = new PrismaClient({ adapter });

    const users = await prisma.user.findMany();

    const result = JSON.stringify(users);

    return new Response(result);

  },

} satisfies ExportedHandler<Env>;

Generate Prisma Client and configure the development and production secrets as shown in this section. Keep database credentials in Worker secrets and never include them in browser-delivered code.

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:

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.

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

}
title="prisma.config.ts"
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:

title=".dev.vars"
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:

title=".dev.vars"
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 dotenv to 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.json that reads .dev.vars via dotenv. You can then execute prisma commands 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_URL and any other relevant env vars into a new file called .env which 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_URL
Bash
pnpm dlx wrangler secret put DATABASE_URL
Bash
yarn dlx wrangler secret put DATABASE_URL
Bash
npx wrangler secret put DATABASE_URL

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.

[!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, use an engine-less Prisma Client with a compatible driver adapter or upgrade to a plan with a larger limit.

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 pg don't work because pg itself currently does not work with @cloudflare/next-on-pages (see next-on-pages issue #605).

If you find that this has changed, let us know on Discord.

Some frameworks (e.g. hono) use node instead of wrangler for running Workers locally. If you're using such a framework or are running your Worker locally with node for another reason, you need to set the PRISMA_CLIENT_FORCE_WASM environment variable:

export PRISMA_CLIENT_FORCE_WASM=1

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@6.19.3 --dev&& bun add @prisma/client@6.19.3

bunx --bun prisma init --output ../generated/prisma
Bash
pnpm create cloudflare prisma-cloudflare-worker-example --type hello-world
cd prisma-cloudflare-worker-example
pnpm add prisma@6.19.3 --save-dev&& pnpm add @prisma/client@6.19.3
pnpm prisma init --output ../generated/prisma
Bash
yarn create cloudflare prisma-cloudflare-worker-example --type hello-world
cd prisma-cloudflare-worker-example
yarn add prisma@6.19.3 --dev&& yarn add @prisma/client@6.19.3
yarn prisma init --output ../generated/prisma
Bash
npm create cloudflare@latest prisma-cloudflare-worker-example -- --type hello-world
cd prisma-cloudflare-worker-example
npm install prisma@6.19.3 --save-dev && npm install @prisma/client@6.19.3
npx prisma init --output ../generated/prisma

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:

prisma
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:

First, ensure that the database connection is configured properly. Database connection URLs are configured in prisma.config.ts:

title="schema.prisma"
generator client {

  provider = "prisma-client"

  output   = "./generated"

}

datasource db {

  provider = "postgresql"

}
title="prisma.config.ts"
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:

title=".dev.vars"
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:

title="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:

title="bun"
bun run env npx prisma
pnpm
pnpm run env npx prisma
yarn
yarn env npx prisma
npm
npm run env -- npx prisma

Next, install the required packages:

title="bun"
bun add @prisma/adapter-pg@6.19.3
pnpm
pnpm add @prisma/adapter-pg@6.19.3
yarn
yarn add @prisma/adapter-pg@6.19.3
npm
npm install @prisma/adapter-pg@6.19.3

In your wrangler.jsonc file, add the following lines:

title="wrangler.jsonc"
{

  "compatibility_flags": [

    "nodejs_compat"

  ],

  "compatibility_date": "2026-08-23"

}

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):

title="bun"
bun run env npx prisma migrate dev --name init
pnpm
pnpm run env npx prisma migrate dev --name init
yarn
yarn env npx prisma migrate dev --name init
npm
npm run env -- npx prisma migrate dev --name init

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);

    return new Response(result);

  },

};

To run the Worker locally, you can run the wrangler dev command:

title="bun"
bunx wrangler dev
pnpm
pnpm dlx wrangler dev
yarn
yarn dlx wrangler dev
npm
npx wrangler dev

To deploy the Worker, you first need to the DATABASE_URL environment variable via the wrangler CLI:

bunx wrangler secret put DATABASE_URL
Bash
pnpm dlx wrangler secret put DATABASE_URL
Bash
yarn dlx wrangler secret put DATABASE_URL
Bash
npx wrangler secret put DATABASE_URL

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.

[!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:

title="bun"
bunx wrangler deploy
pnpm
pnpm dlx wrangler deploy
yarn
yarn dlx wrangler deploy
npm
npx wrangler deploy

The 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-planetscale database adapter (learn more in How to use the PlanetScale serverless driver with Prisma ORM (Preview))

  • manually remove the conflicting cache field:

    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 });
    
        // ...
    
      },
    
    };

First, ensure that the database connection is configured properly. In your Prisma schema, set the url of the datasource block to the DATABASE_URL environment variable:

title="schema.prisma"
generator client {

  provider = "prisma-client"

  output   = "./generated"

}

datasource db {

  provider     = "mysql"

  relationMode = "prisma" // required for PlanetScale (as by default foreign keys are disabled)

}
title="prisma.config.ts"
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:

title=".dev.vars"
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:

title="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:

title="bun"
bun run env npx prisma
pnpm
pnpm run env npx prisma
yarn
yarn env npx prisma
npm
npm run env -- npx prisma

Next, install the required packages:

title="bun"
bun add @prisma/adapter-planetscale@6.19.3
pnpm
pnpm add @prisma/adapter-planetscale@6.19.3
yarn
yarn add @prisma/adapter-planetscale@6.19.3
npm
npm install @prisma/adapter-planetscale@6.19.3

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):

title="bun"
bun run env npx prisma db push
pnpm
pnpm run env npx prisma db push
yarn
yarn env npx prisma db push
npm
npm run env -- npx prisma db push

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);

    return new Response(result);

  },

};

To run the Worker locally, you can run the wrangler dev command:

title="bun"
bunx wrangler dev
pnpm
pnpm dlx wrangler dev
yarn
yarn dlx wrangler dev
npm
npx wrangler dev

To deploy the Worker, you first need to the DATABASE_URL environment variable via the wrangler CLI:

bunx wrangler secret put DATABASE_URL
Bash
pnpm dlx wrangler secret put DATABASE_URL
Bash
yarn dlx wrangler secret put DATABASE_URL
Bash
npx wrangler secret put DATABASE_URL

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.

[!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:

title="bun"
bunx wrangler deploy
pnpm
pnpm dlx wrangler deploy
yarn
yarn dlx wrangler deploy
npm
npx wrangler deploy

The command will output the URL where you can access the deployed Worker.

If you are using a Neon database, you need to:

First, ensure that the database connection is configured properly. Database connection URLs are configured in prisma.config.ts:

title="schema.prisma"
generator client {

  provider = "prisma-client"

  output   = "./generated"

}

datasource db {

  provider = "postgresql"

}
title="prisma.config.ts"
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:

title=".dev.vars"
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:

title="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:

title="bun"
bun run env npx prisma
pnpm
pnpm run env npx prisma
yarn
yarn env npx prisma
npm
npm run env -- npx prisma

Next, install the required packages:

title="bun"
bun add @prisma/adapter-neon@6.19.3
pnpm
pnpm add @prisma/adapter-neon@6.19.3
yarn
yarn add @prisma/adapter-neon@6.19.3
npm
npm install @prisma/adapter-neon@6.19.3

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):

title="bun"
bun run env npx prisma migrate dev --name init
pnpm
pnpm run env npx prisma migrate dev --name init
yarn
yarn env npx prisma migrate dev --name init
npm
npm run env -- npx prisma migrate dev --name init

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);

    return new Response(result);

  },

};

To run the Worker locally, you can run the wrangler dev command:

title="bun"
bunx wrangler dev
pnpm
pnpm dlx wrangler dev
yarn
yarn dlx wrangler dev
npm
npx wrangler dev

To deploy the Worker, you first need to the DATABASE_URL environment variable via the wrangler CLI:

bunx wrangler secret put DATABASE_URL
Bash
pnpm dlx wrangler secret put DATABASE_URL
Bash
yarn dlx wrangler secret put DATABASE_URL
Bash
npx wrangler secret put DATABASE_URL

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.

[!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:

title="bun"
bunx wrangler deploy
pnpm
pnpm dlx wrangler deploy
yarn
yarn dlx wrangler deploy
npm
npx wrangler deploy

The command will output the URL where you can access the deployed Worker.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu