PgBeam Docs

Prisma

Connect Prisma to your PostgreSQL database through PgBeam for connection pooling, caching, and global routing.

Connect your Prisma application to PgBeam by updating the DATABASE_URL environment variable. No changes to your Prisma schema, queries, or application code are required.

Setup

Update your connection string

Point DATABASE_URL at your PgBeam project hostname:

.env
DATABASE_URL="postgresql://user:pass@abc.aws.pgbeam.app:5432/mydb"

Verify your schema

No changes needed to schema.prisma — the postgresql provider works as-is:

schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Reduce Prisma's connection pool size

PgBeam handles connection pooling at the proxy layer, so Prisma does not need a large local pool. Append connection_limit to your connection string:

.env
DATABASE_URL="postgresql://user:pass@abc.aws.pgbeam.app:5432/mydb?connection_limit=5"

Run a test query

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

If this returns results, Prisma is connected through PgBeam.

Connection pool sizing

By default, Prisma creates a pool of num_cpus * 2 + 1 connections. Since PgBeam manages upstream pooling, you should reduce this to avoid holding unnecessary upstream connections:

Deployment typeRecommended connection_limit
Single server5-10
Multiple replicas/pods3-5 per instance
Serverless (Lambda)1-2

With PgBeam in transaction pool mode, Prisma connections are multiplexed upstream. A pool of 5 per instance is sufficient for most workloads, even at high concurrency.

Prisma Migrate

Run migrations against the origin

Run Prisma migrations directly against your origin database, not through PgBeam. Migrations use advisory locks and other session features that should bypass the proxy.

Set a separate environment variable for migrations or override inline:

Run migrations against origin
DATABASE_URL="postgresql://user:pass@db.example.com:5432/mydb" npx prisma migrate deploy

This applies to both prisma migrate deploy (production) and prisma migrate dev (development).

Caching with Prisma

For standard Prisma Client queries (findMany, findUnique, etc.), PgBeam automatically tracks the generated SQL shapes. Enable caching for these shapes through Cache Rules in the dashboard — no code changes needed.

Raw queries with annotations

For Prisma raw queries, you can use inline SQL annotations for fine-grained cache control:

Cache control with raw queries
// Cache for 5 minutes
const products = await prisma.$queryRaw`
  /* @pgbeam:cache maxAge=300 */ SELECT * FROM products WHERE category = ${category}
`;

// Disable caching for a specific query
const balance = await prisma.$queryRaw`
  /* @pgbeam:cache noCache */ SELECT balance FROM accounts WHERE id = ${accountId}
`;

Read replicas with Prisma

Route read queries to replicas using the /* @pgbeam:replica */ annotation in raw queries:

Replica routing
// Route to a read replica
const products = await prisma.$queryRaw`
  /* @pgbeam:replica */ SELECT * FROM products WHERE active = true
`;

// Combine replica routing with caching
const categories = await prisma.$queryRaw`
  /* @pgbeam:replica */ /* @pgbeam:cache maxAge=600 */ SELECT * FROM categories
`;

Standard Prisma Client queries (findMany, etc.) always go to the primary database. To use replica routing, use raw queries with the annotation.

See Read Replicas for details on replica setup and routing behavior.

Debugging

Enable PgBeam debug output to verify caching and routing behavior from within Prisma:

await prisma.$executeRaw`SET pgbeam.debug = on`;

const result = await prisma.$queryRaw`SELECT * FROM users WHERE id = ${userId}`;
// Check server logs for: NOTICE: pgbeam: cache=hit age=12s ttl=60s swr=30s

Common issues

IssueCauseFix
"Too many connections" on startupPrisma pool too largeAdd ?connection_limit=5 to DATABASE_URL
Prepared statement errorsUsing transaction pool modeSwitch to session pool mode, or avoid prepared statements
Migrations fail through PgBeamAdvisory locks not supported in transaction modeRun migrations against origin directly
Stale data after writesCache returning old resultsUse noCache annotation or disable cache for that query shape

Further reading

On this page