# Prisma ORM Support for Edge Functions is Now in Preview URL: https://www.prisma.io/blog/prisma-orm-support-for-edge-functions-is-now-in-preview Published: 2024-03-12 Authors: Nikolas Burk Tags: announcement, orm Description: We're thrilled to share that you can now access your database with Prisma ORM from Vercel Edge Functions and Cloudflare Workers. We’re thrilled to share that support for edge functions is in Preview! You can now access your database with Prisma ORM from Vercel Edge Functions, Vercel Edge Middleware, Cloudflare Workers, and Cloudflare Pages. [Try it out](https://www.prisma.io/docs/orm/v7/prisma-client/deployment/edge/overview)! ## What are edge functions? [#what-are-edge-functions] Edge functions are a form of lightweight serverless compute that's distributed across the globe. They allow you to deploy and run your apps as closely as possible to your end users. ![](https://www.prisma.io/blog/prisma-orm-support-for-edge-functions-is-now-in-preview/imgs/cdc1687a8bc84dd978cd3e2270618719a6da7207-1920x1080.png) ### Edge functions can make your app faster [#edge-functions-can-make-your-app-faster] Thanks to the geographically distributed nature of edge functions, the distance between the user and the data center is reduced. This decreases request latency and improves response times, making edge functions a great approach to increase performance and notably improve the user experience of an app. ### Technical constraints in edge functions [#technical-constraints-in-edge-functions] Vercel Edge Functions and Cloudflare Workers don't use the standard Node.js runtime. Instead, they are running code in [V8 isolates](https://www.cloudflare.com/learning/serverless/glossary/what-is-chrome-v8/). As a consequence, these edge functions only have access to a small subset of the standard Node.js APIs and also have constrained computing resources (CPU and memory). In particular, the constraint of not being able to freely open TCP connections makes it difficult to talk to a traditional database from an edge function. While Cloudflare has introduced a [`connect()`](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/) API that enables limited TCP connections, this still only enables database access using specific database drivers that are compatible with that API. > **Note:** In the Node.js ecosystem, the most popular traditional database driver [compatible with Cloudflare Workers](https://developers.cloudflare.com/workers/tutorials/postgres/) is [`node-postgres`](https://node-postgres.com/) for PostgreSQL. However, there is also [work being done](https://github.com/sidorares/node-mysql2/pull/2289) to make MySQL compatible with Cloudflare Workers in the `node-mysql2` driver. Modern database providers, such as [Neon](https://neon.tech/docs/serverless/serverless-driver) or [PlanetScale](https://planetscale.com/docs/tutorials/planetscale-serverless-driver), have worked around this limitation by releasing [*serverless drivers*](https://www.prisma.io/blog/serverless-database-drivers-KML1ehXORxZV#what-are-serverless-database-drivers) that talk to the database via HTTP. ## Database access in edge functions with Prisma ORM 🎉 [#database-access-in-edge-functions-with-prisma-orm-] While it was possible to use Prisma ORM in an edge function in earlier versions, this always required usage of [Prisma Accelerate](https://www.prisma.io/data-platform/accelerate) as a proxy between the edge function and the database. ![](https://www.prisma.io/blog/prisma-orm-support-for-edge-functions-is-now-in-preview/imgs/4b2cd3e2d1da28a2f29ced7d34f75ac7bbd08f94-2532x1210.png) It was not possible to "just" deploy an app with Prisma ORM to the edge due to the technical constraints mentioned above: * Database access only works with specific drivers (either a serverless driver or a driver that's compatible with Cloudflare's `connect()`). The problem here was that Prisma ORM only used to have *built-in* drivers in its query engine and thus couldn't use the compatible Node.js drivers. * Size limitations of the application bundle that's uploaded to an edge function made it impossible to use Prisma ORM because its query engine was too large and exceeded the size limit. * Edge functions only allows access to a limited set of Node.js APIs. Some of these APIs are required for Prisma Client to work though, so not having access to these requires Prisma Client to work around some of the limitations. ![](https://www.prisma.io/blog/prisma-orm-support-for-edge-functions-is-now-in-preview/imgs/b67a096af36af4026cd5c6b36b34a7693d0f2ce1-2532x1210.png) We are excited that the [`v5.11.0`](https://github.com/prisma/orm/releases/tag/5.11.0) release lifts these restrictions and enables running Prisma ORM in edge functions in Preview 🎉 ![](https://www.prisma.io/blog/prisma-orm-support-for-edge-functions-is-now-in-preview/imgs/4a84546e5ae706f5a2a15e67a4757260d14b1273-2532x1210.png) Thanks to the [driver adapters](https://www.prisma.io/docs/orm/v7/core-concepts/supported-databases/database-drivers#driver-adapters) Preview feature that was recently introduced, developers can now use Prisma ORM with their favorite database drivers from the Node.js ecosystem! Additionally, we have been able to drastically reduce the size of Prisma ORM's query engine so that it now fits into the limited runtime environment of an edge function. ## How to use Prisma ORM in an edge function [#how-to-use-prisma-orm-in-an-edge-function] > 🔬 If you're interested in seeing an example in action, we put together a little [GitHub repository](https://github.com/prisma/nextjs-edge-functions/) demonstrating how to access your database using Prisma ORM with Vercel Edge Functions. Follow along to learn how to get up and running with Prisma ORM in a **Cloudflare Worker** using a **PlanetScale database** (or [check our docs](https://www.prisma.io/docs/orm/v7/prisma-client/deployment/edge/overview) to use a different combination of edge deployment and database provider). ### 0. Prerequisites [#0-prerequisites] Before running through the following steps, make sure you have: * Node.js installed on your machine * a Cloudflare account * a PlanetScale instance up and running and its connection string available ### 1. Set up your application [#1-set-up-your-application] Initialize your project using the [`create-cloudflare-cli`](https://www.npmjs.com/package/create-cloudflare) and follow the steps in the CLI wizard and select the default options for the prompts: ``` npm create cloudflare@latest prisma-cloudflare-worker-example -- --type hello-world ``` ### 2. Set up Prisma [#2-set-up-prisma] Navigate into the new directory and install the Prisma CLI: ``` cd prisma-cloudflare-worker-example npm install --save-dev prisma@7.9.1 ``` Next, initialize Prisma in your project with the following command: ``` npx prisma init --datasource-provider mysql ``` The above command: * Created the Prisma schema file in `prisma/schema.prisma` * Created a `.env` file to store environment variables The `.env` file contains a placeholder `DATABASE_URL` environment variable. Update the value with the actual connection string that connects to your PlanetScale database. It may look similar to this: ```shell # .env DATABASE_URL="mysql://USERNAME:PASSWORD@aws.connect.psdb.cloud/DATABASE?sslaccept=strict" ``` > **Note:** The connection string above uses placeholders for the *username*, *password* and *name* of your database. Be sure to replace these with the values for your own database. Update your Prisma schema to look as follows: ```prisma generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters"] } datasource db { provider = "mysql" url = env("DATABASE_URL") relationMode = prisma // required for PlanetScale } model Log { id Int @id @default(autoincrement()) level Level message String meta Json } enum Level { Info Warn Error } ``` The above Prisma schema: * Enables the `driverAdapters` Preview feature flag * Defines a `Log` model and `Level` enum To map your data model to the database, you need to use the `prisma db push` CLI command: ``` npx prisma db push ``` This created a new `Log` table in your database that you can now view in the PlanetScale dashboard. ### 3. Write the Cloudflare Worker function [#3-write-the-cloudflare-worker-function] In your `wrangler.toml` file, add a `[vars]` key and your database connection string (like before, replace the placeholders for `USERNAME`, `PASSWORD` and `DATABASE` with the values of your own PlanetScale instance): ```toml # wrangler.toml name = "prisma-cloudflare-accelerate" main = "src/main.ts" compatibility_date = "2022-11-07" [vars] DATABASE_URL = "mysql://USERNAME:PASSWORD@aws.connect.psdb.cloud/DATABASE?sslaccept=strict" ``` > **Note:** Since this is a demo app, we're adding the plain connection string into `wrangler.toml`. However, as this file is typically committed into version control, you should never do this in production because that would publicly expose your database connection. Instead, use [Cloudflare's configuration for secrets](https://developers.cloudflare.com/workers/configuration/secrets/). Next, install the PlanetScale serverless database driver and its [driver adapter](https://www.prisma.io/docs/orm/v7/core-concepts/supported-databases/database-drivers#serverless-driver-adapters): ``` npm install @prisma/adapter-planetscale @planetscale/database ``` Update the example Cloudflare Worker snippet in the `src/index.ts` file with the following code: ```ts import { PrismaClient } from '@prisma/client' import { Client } from '@planetscale/database' import { PrismaPlanetScale } from '@prisma/adapter-planetscale' export interface Env { DATABASE_URL: string } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { const config = { url: env.DATABASE_URL, // see https://github.com/cloudflare/workerd/issues/698 fetch: (url: any, init: any) => { delete init['cache'] return fetch(url, init) }, } const client = new Client(config) const adapter = new PrismaPlanetScale(client) const prisma = new PrismaClient({ adapter }) await prisma.log.create({ data: { level: 'Info', message: `${request.method} ${request.url}`, meta: { headers: JSON.stringify(request.headers), }, }, }) const logs = await prisma.log.findMany({ take: 20, orderBy: { id: 'desc', }, }) console.log(JSON.stringify(logs)) return new Response(JSON.stringify(logs)) }, } ``` Start up the application: ``` npm run dev ``` From the terminal output, you can now open the URL pointing to `localhost` or hit the `b` key to open your browser and invoke the Worker function. If everything went well, you'll see output looking similar to this: ```js [{ "id": 1, "level": "Info", "message": "GET http://localhost:63098/", "meta": { "headers": "{}" } }] ``` ### 4. Publish to Cloudflare Workers [#4-publish-to-cloudflare-workers] You can now deploy the application by running the following command: ``` npm run deploy ``` This command will deploy your edge function to Cloudflare and output the URL where it can be accessed. ## Try it out and share your feedback [#try-it-out-and-share-your-feedback] We would love to know what you think! Try out the new support for edge deployments using [Vercel](https://www.prisma.io/docs/orm/v7/prisma-client/deployment/edge/deploy-to-vercel) or [Cloudflare](https://www.prisma.io/docs/orm/v7/prisma-client/deployment/edge/deploy-to-cloudflare) and share your feedback with us via [X](https://pris.ly/x) or [Discord](http://pris.ly/discord) 🚀 If you run into any issues, you can create a bug report [here](https://github.com/prisma/orm/issues/new/choose).