October 06, 2023
Support for Serverless Database Drivers in Prisma ORM Is Now in Preview
Prisma is releasing Preview support for serverless database drivers from Neon and PlanetScale. This feature allows Prisma users to leverage the existing database drivers for communication with their database without long-lived TCP connections!
What are serverless database drivers?
Traditionally, database drivers establish a long-lived TCP connection with a database to communicate. Even though a TCP connection has some overhead at the start, continued communication has little to no overhead, making it ideal for serverful deployments.
However, long-lived connections can cause problems in serverless environments. Given the ephemeral nature of serverless functions, it can become a chore to track connections, close idle ones, handle zombies, and maintain an internal connection pool so your database doesn’t get overwhelmed. On top of this, a growing number of cloud providers disallow arbitrary TCP connections, making it challenging to use existing databases that rely on TCP connections.
Serverless functions can quickly exhaust database connectionsAs a response to the above issues, Prisma developed Prisma Accelerate in order to provide a better experience for apps running on serverless functions. In addition, several database providers have also developed their own database driver libraries. These drivers use different protocols, such as HTTP or WebSocket, rather than traditional TCP connections, and as such are ideal for serverless, which is evolving rapidly.
So, how do these serverless drivers fit in with Prisma?
Prisma ORM now supports serverless drivers
Since its initial release, a crucial part of the Prisma ORM has been the Query Engine. Written in Rust, the Query Engine allows for Prisma Client queries to be reliably and efficiently translated into SQL statements, which are then executed via the included database drivers. This system has worked well in the past, but a few months ago, we noticed the trend of new database providers providing serverless database drivers written in JavaScript, that talk to special endpoints via HTTP. Our team knew building Rust-based implementations that communicated with these new endpoints would be a massive undertaking.
Prisma Client communicating with a database without a driver adapter.Also, while Prisma ORM works with many database engines and providers, it could only connect to these databases via a direct TCP connection, or through a connection pooler such as Prisma Accelerate. Today, both of these issues are resolved with the introduction of driver adapters that enables the Prisma ORM to use existing JavaScript database drivers when connecting to supported databases.
Today, we are releasing two driver adapters: @prisma/adapter-neon
and @prisma/adapter-planetscale
. These adapters act as translators between Prisma Client and JavaScript serverless database drivers. If you are using a database driver and a driver adapter, your app no longer requires a direct TCP connection to your database in order to function and instead communicates with your database over HTTP or a WebSocket connection. Prisma uses the Rust engine to translate Prisma Client queries to SQL and then run these queries via these drivers. With this setup, we’re able to offer the best of both worlds: a battle-tested query engine and the ability to use an increasing number of providers in Prisma-powered codebases.
Now, the only requirement is the ability to make HTTP or WebSocket requests, dramatically simplifying Function-as-a-Service (FaaS) deployments.
How to use Prisma ORM with serverless database drivers
Setting up Prisma to work with the Neon or PlanetScale serverless database drivers is easy:
- Set up your database driver as usual
- Pass it to the corresponding Prisma driver adapter
- Create a Prisma Client with that driver adapter
First, install prisma
and @prisma/client
to at least version 5.4.1
. Also install dotenv
so that any environment variable defined in your .env
file will be available in your script via process.env
.
npm install --save-dev prisma@^5.4.1npm install @prisma/client@^5.4.1npm install dotenvCopy
Now, you can set up Prisma Client as below.
Use Neon with @neondatabase/serverless
After creating your database on Neon you'll need to install the @prisma/adapter-neon
driver adapter, Neon’s serverless database driver @neondatabase/serverless
, and ws
to set up a WebSocket connection for use by Neon.
npm install @prisma/adapter-neonnpm install @neondatabase/serverlessnpm install wsCopy
Then make sure your Neon database connection string is copied over to your .env
file. The connection string will start with postgres://
.
// .envDATABASE_URL="postgres://..."
You can now reference this environment variable in your schema.prisma
datasource. Make sure you also include the driverAdapters
Preview feature.
// schema.prismagenerator client {provider = "prisma-client-js"previewFeatures = ["driverAdapters"]}datasource db {provider = "postgresql"url = env("DATABASE_URL")}Copy
Now run npx prisma generate
to re-generate Prisma Client and make the Preview feature available in your app.
After the above setup, you can continue in your script:
- Import packages
- Set up the Neon serverless database driver
- Instantiate the Prisma Neon adapter with the Neon serverless database driver
- Pass the driver adapter to the Prisma Client instance
// Import needed packagesimport { Pool, neonConfig } from '@neondatabase/serverless';import { PrismaNeon } from '@prisma/adapter-neon';import { PrismaClient } from '@prisma/client';import dotenv from 'dotenv';import ws from 'ws';// Setupdotenv.config()neonConfig.webSocketConstructor = ws;const connectionString = `${process.env.DATABASE_URL}`;// Init prisma clientconst pool = new Pool({ connectionString });const adapter = new PrismaNeon(pool);const prisma = new PrismaClient({ adapter });// Use Prisma Client as normalCopy
Now your code has built-in benefits of the Neon serverless driver, such as WebSocket connections and message pipelining, while Prisma covers connection creation and destruction, error handling, and type safety. If you have any feedback about our Neon Serverless Driver support, please leave a comment on our dedicated GitHub issue and we'll use it as we continue development.
Use PlanetScale with @planetscale/database
After getting started with PlanetScale you can use the PlanetScale serverless driver to connect to your database. You will need to install the @prisma/adapter-planetscale
driver adapter, the @planetscale/database
serverless driver, and undici
to provide a fetch
function to the PlanetScale driver.
npm install @prisma/adapter-planetscalenpm install @planetscale/databasenpm install undici
Then make sure your PlanetScale database connection string is copied over to your .env
file. The connection string will start with mysql://
// .envDATABASE_URL="mysql://..."
You can now reference this environment variable in your schema.prisma
datasource. Make sure you also include the driverAdapters
Preview feature.
// schema.prismagenerator client {provider = "prisma-client-js"previewFeatures = ["driverAdapters"]}datasource db {provider = "mysql"url = env("DATABASE_URL")relationMode = "prisma"}Copy
Now run npx prisma generate
to re-generate Prisma Client and make the Preview feature available in your app.
// import needed packagesimport { Client } from "@planetscale/database"import { PrismaPlanetScale } from "@prisma/adapter-planetscale"import { PrismaClient } from "@prisma/client"// setupdotenv.config();const connectionString = `${process.env.DATABASE_URL}`;// init prisma clientconst client = new Client({ url: process.env.DATABASE_URL })const adapter = new PrismaPlanetScale(client)const prisma = new PrismaClient({ adapter })Copy
Prior to Prisma version 5.7.0, the setup for the PlanetScale driver adapter was slightly different. This method used connect
instead of PlanetScale's Client
.
// Import needed packagesimport { connect } from '@planetscale/database';import { PrismaPlanetScale } from '@prisma/adapter-planetscale';import { PrismaClient } from '@prisma/client';import dotenv from 'dotenv';import { fetch as undiciFetch } from 'undici';
// setupdotenv.config();const connectionString = `${process.env.DATABASE_URL}`;
// init prisma clientconst connection = connect({ url: connectionString, fetch: undiciFetch });const adapter = new PrismaPlanetScale(connection);const prisma = new PrismaClient({ adapter });
// Use Prisma Client as normal
Your Prisma Client instance now uses PlanetScale's database-js
which can improve connection reliability and performance. It uses HTTP requests instead of Prisma’s connection pool, but Prisma will continue to handle error handling and type safety. If you have any feedback about our PlanetScale Serverless Driver support, please leave a comment on our dedicated GitHub issue and we'll use it as we continue development.
While the setup of the database driver and the driver adapter differ from our existing Getting Started guides, your Prisma Client will feel very familiar, except now it is taking advantage of your chosen database client and communicates with your database without using TCP connections.
Wrapping up
We're excited that Prisma users can now take advantage of the Neon and PlanetScale serverless database drivers. These drivers are perfect for serverless environments or areas where long-lived TCP connections are not possible.
Prisma Client and the new driver adapters feature currently do not support Edge Functions deployments such as CloudFlare Workers or Vercel Edge Functions yet. If you want to test the Neon or PlanetScale Serverless Driver in Edge Functions environments, make sure to submit a response to our survey so that you will be considered for Early Access to our edge function support as well. We'll have news soon.
We would love to know what you think! Try out the driverAdapters
Preview feature and pass any feedback you have via our GitHub disccussions for Neon and PlanetScale or on our Discord.