Best practices for using Prisma Client with Next.js

Problem

Many users have come across this warning while working with in development:

warn(prisma-client) There are already 10 instances of Prisma Client actively running.

There's a related and for the same.

In development, the command next dev clears Node.js cache on run. This in turn initializes a new PrismaClient instance each time due to hot reloading that creates a connection to the database. This can quickly exhaust the database connections as each PrismaClient instance holds its own connection pool.

Solution

The solution in this case is to instantiate a single instance PrismaClient and save it on the object. Then we keep a check to only instantiate PrismaClient if it's not on the globalThis object otherwise use the same instance again if already present to prevent instantiating extra PrismaClient instances.

db.ts
1import { PrismaClient } from '@prisma/client'
2
3const prismaClientSingleton = () => {
4 return new PrismaClient()
5}
6
7declare global {
8 var prisma: undefined | ReturnType<typeof prismaClientSingleton>
9}
10
11const prisma = globalThis.prisma ?? prismaClientSingleton()
12
13export default prisma
14
15if (process.env.NODE_ENV !== 'production') globalThis.prisma = prisma

You can extend Prisma Client using a Prisma Client extension by appending the $extends client method when instantiating Prisma Client as follows:

import { PrismaClient } from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient().$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(user) {
return `${user.firstName} ${user.lastName}`
},
},
},
},
})
}

After creating this file, you can now import the extended PrismaClient instance anywhere in your Next.js pages as follows:

// e.g. in `pages/index.tsx`
import prisma from './db'
export const getServerSideProps = async () => {
const posts = await prisma.post.findMany()
return { props: { posts } }
}

Next.js caching

When using Next.js, you may run into an issue where . In these cases, it's important to to "force-dynamic" so data is correctly returned from your Prisma Client queries.

You can add "force-dynamic" like this:

import { NextRequest, NextResponse } from 'next/server'
import prisma from './db'
export const dynamic = 'force-dynamic'
export async function GET(request: NextRequest, response: NextResponse) {
// your code would go here
}