apps/docs/content/docs.v6/guides/multiple-databases.mdx
This guide shows you how to use multiple databases using Prisma ORM in a single Next.js app. You will learn how to connect to two different Prisma Postgres databases, manage migrations, and deploy your application to Vercel. This approach is useful for multi-tenant applications or when you need to separate concerns when managing connections to multiple databases.
Before you begin, make sure that you have the following:
Create a new Next.js app using create-next-app from your desired directory:
npx create-next-app@latest my-multi-client-app
You will be prompted to answer a few questions about your project. Select all of the defaults.
:::info
For completeness, those are:
src directory@/*:::
Then, navigate to the project directory:
cd my-multi-client-app
In this section, you will create two separate Prisma Postgres instances—one for user data and one for post data. You will also configure the Prisma schema and environment variables for each.
First, install Prisma and the required dependencies:
npm install prisma tsx @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg dotenv pg
:::info
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of @prisma/adapter-pg. For more information, see Database drivers.
:::
You have installed the required dependencies for the project.
Initialize Prisma with a Prisma Postgres instance by running:
npx prisma@latest init --db
:::info
If you are not using a Prisma Postgres database, do not use the --db flag. Instead, create two PostgreSQL database instances and add their connection URLs to the .env file as PPG_USER_DATABASE_URL and PPG_POST_DATABASE_URL.
:::
Follow the prompts to name your project and choose a database region.
The prisma@latest init --db command:
prisma directory containing a schema.prisma file for your database models..env file with your DATABASE_URL (e.g., DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require").Rename the prisma folder to prisma-user-database:
mv prisma prisma-user-database
Edit your .env file to rename DATABASE_URL to PPG_USER_DATABASE_URL:
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" // [!code --]
PPG_USER_DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" // [!code ++]
Open prisma-user-database/schema.prisma file and update it to define a User model. Also, set the environment variable and specify a custom output directory for the generated Prisma Client:
generator client {
provider = "prisma-client"
output = "../prisma-user-database/user-database-client-types" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
Create a prisma.config.ts file for the user database:
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma-user-database/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma-user-database/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("PPG_USER_DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
:::note
You'll need to install the dotenv package if you haven't already:
npm install dotenv
:::
Your user database schema is now ready.
Repeat the initialization for the post database:
npx prisma init --db
After following the prompts, rename the new prisma folder to prisma-post-database:
mv prisma prisma-post-database
Rename the DATABASE_URL variable in .env to PPG_POST_DATABASE_URL:
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" // [!code --]
PPG_POST_DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" // [!code ++]
Edit the prisma-post-database/schema.prisma file to define a Post model. Also, update the datasource URL and set a custom output directory:
generator client {
provider = "prisma-client"
output = "../prisma-post-database/post-database-client-types" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
} // [!code ++]
Create a prisma.config.ts file for the post database:
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma-post-database/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma-post-database/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("PPG_POST_DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
Your post database schema is now set.
To simplify your workflow, add helper scripts to your package.json file that run Prisma commands for both databases:
"script":{
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma", // [!code ++]
"generate": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma", // [!code ++]
"migrate": "npx prisma migrate dev --schema ./prisma-user-database/schema.prisma && npx prisma migrate dev --schema ./prisma-post-database/schema.prisma", // [!code ++]
"deploy": "npx prisma migrate deploy --schema ./prisma-user-database/schema.prisma && npx prisma migrate deploy --schema ./prisma-post-database/schema.prisma", // [!code ++]
"studio": "npx prisma studio --schema ./prisma-user-database/schema.prisma --port 5555 & npx prisma studio --schema ./prisma-post-database/schema.prisma --port 5556" // [!code ++]
}
Here is an explanation of the custom scripts:
postinstall: Runs immediately after installing dependencies to generate Prisma Clients for both the user and post databases using their respective schema files.generate: Manually triggers the generation of Prisma Clients for both schemas, ensuring your client code reflects the latest models.migrate: Applies pending migrations in development mode for both databases using Prisma Migrate, updating their schemas based on changes in your Prisma files.deploy: Executes migrations in a production environment, synchronizing your live databases with your Prisma schemas.studio: Opens Prisma Studio for both databases simultaneously on different ports (5555 for the user database and 5556 for the post database) for visual data management.Run the migrations:
npm run migrate
When prompted, name the migration for each database accordingly.
Next, create a lib folder to store helper files for instantiating and exporting your Prisma Clients:
mkdir -p lib && touch lib/user-prisma-client.ts lib/post-prisma-client.ts
In lib/user-prisma-client.ts, add the following code:
import { PrismaClient } from "../prisma-user-database/user-database-client-types/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.PPG_USER_DATABASE_URL, // [!code ++]
}); // [!code ++]
const getPrisma = () =>
// [!code ++]
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
const globalForUserDBPrismaClient = global as unknown as {
// [!code ++]
userDBPrismaClient: ReturnType<typeof getPrisma>; // [!code ++]
}; // [!code ++]
export const userDBPrismaClient = globalForUserDBPrismaClient.userDBPrismaClient || getPrisma(); // [!code ++]
if (process.env.NODE_ENV !== "production")
// [!code ++]
globalForUserDBPrismaClient.userDBPrismaClient = userDBPrismaClient; // [!code ++]
In lib/post-prisma-client.ts, add this code:
import { PrismaClient } from "../prisma-post-database/post-database-client-types/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.PPG_POST_DATABASE_URL, // [!code ++]
}); // [!code ++]
const getPrisma = () =>
// [!code ++]
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
const globalForPostDBPrismaClient = global as unknown as {
// [!code ++]
postDBPrismaClient: ReturnType<typeof getPrisma>; // [!code ++]
}; // [!code ++]
export const postDBPrismaClient = globalForPostDBPrismaClient.postDBPrismaClient || getPrisma(); // [!code ++]
if (process.env.NODE_ENV !== "production")
// [!code ++]
globalForPostDBPrismaClient.postDBPrismaClient = postDBPrismaClient; // [!code ++]
Modify your application code to fetch data from both databases. Update the app/page.tsx file as follows:
import { postDBPrismaClient } from "@/lib/post-prisma-client"; // [!code ++]
import { userDBPrismaClient } from "@/lib/user-prisma-client"; // [!code ++]
export default async function Home() { // [!code ++]
const user = await userDBPrismaClient.user.findFirst(); // [!code ++]
const post = await postDBPrismaClient.post.findFirst(); // [!code ++]
return ( // [!code ++]
<main className="min-h-screen bg-gray-50 py-12"> // [!code ++]
<div className="max-w-4xl mx-auto px-4"> // [!code ++]
<header className="mb-12 text-center"> // [!code ++]
<h1 className="text-5xl font-extrabold text-gray-900">Multi-DB Showcase</h1> // [!code ++]
<p className="mt-4 text-xl text-gray-600"> // [!code ++]
Data fetched from two distinct databases. // [!code ++]
</p> // [!code ++]
</header> // [!code ++]
<section className="mb-8 bg-white shadow-md rounded-lg p-6"> // [!code ++]
<h2 className="text-2xl font-semibold text-gray-800 border-b pb-2 mb-4"> // [!code ++]
User Data // [!code ++]
</h2> // [!code ++]
<pre className="whitespace-pre-wrap text-sm text-gray-700"> // [!code ++]
{user ? JSON.stringify(user, null, 2) : "No user data available."} // [!code ++]
</pre> // [!code ++]
</section> // [!code ++]
<section className="bg-white shadow-md rounded-lg p-6"> // [!code ++]
<h2 className="text-2xl font-semibold text-gray-800 border-b pb-2 mb-4"> // [!code ++]
Post Data // [!code ++]
</h2> // [!code ++]
<pre className="whitespace-pre-wrap text-sm text-gray-700"> // [!code ++]
{post ? JSON.stringify(post, null, 2) : "No post data available."} // [!code ++]
</pre> // [!code ++]
</section> // [!code ++]
</div> // [!code ++]
</main> // [!code ++]
); // [!code ++]
} // [!code ++]
In a separate terminal window, open two instances of Prisma Studio to add data to your databases by running the script:
npm run studio
This will open up two browser windows, one in http://localhost:5555 and one in http://localhost:5556. Navigate to those windows and add sample data to both databases.
Before starting the development server, note that if you are using Next.js v15.2.0, do not use Turbopack as there is a known issue. Remove Turbopack from your dev script by updating your package.json:
"script":{
"dev": "next dev --turbopack", // [!code --]
"dev": "next dev", // [!code ++]
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma",
"generate": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma",
"migrate": "npx prisma migrate dev --schema ./prisma-user-database/schema.prisma && npx prisma migrate dev --schema ./prisma-post-database/schema.prisma",
"deploy": "npx prisma migrate deploy --schema ./prisma-user-database/schema.prisma && npx prisma migrate deploy --schema ./prisma-post-database/schema.prisma",
"studio": "npx prisma studio --schema ./prisma-user-database/schema.prisma --port 5555 & npx prisma studio --schema ./prisma-post-database/schema.prisma --port 5556"
}
In a separate terminal window, start the development server by running:
npm run dev
Navigate to http://localhost:3000 to see your Next.js app display data from both databases:
Congratulations, you have a Next.js app running with two Prisma Client instances querying different databases.
Deploy your app by following these steps:
git add .
git commit -m "Initial commit with Prisma Postgres integration"
git branch -M main
git remote add origin https://github.com/<your-username>/<repository-name>.git
git push -u origin main
<your-username> and <repository-name> with your GitHub username and the name of your repository.
:::DATABASE_URL environment variable:
PPG_USER_DATABASE_URL environment variable:
PPG_USER_DATABASE_URL.env file in your project.PPG_POST_DATABASE_URL environment variable:
PPG_POST_DATABASE_URL.env file in your project.
:::warning
Do not deploy without setting the environment variables. Your deployment will fail if the application cannot connect to the databases.
:::Open the live URL provided by Vercel and verify that your application is working.
Congratulations! You have deployed an application that uses multiple Prisma Clients to query two different databases, and it is now live and fully operational on Vercel.
In this guide, you learned how to use multiple databases using Prisma ORM in a single Next.js app by:
This approach allows you to maintain a clear separation of data models and simplifies multi-tenant or multi-database scenarios.
For further improvements in managing your project, consider using a monorepo setup. Check out our related guides: