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:
DATABASE_URL="postgresql://user:pass@abc.proxy.pgbeam.app:5432/mydb"Verify your schema
No changes needed to schema.prisma. The postgresql provider works as-is:
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:
DATABASE_URL="postgresql://user:pass@abc.proxy.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 type | Recommended connection_limit |
|---|---|
| Single server | 5-10 |
| Multiple replicas/pods | 3-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.
Transaction mode + Prisma prepared statements
New PgBeam databases default to transaction pool mode, where session state
(including prepared statements) is reset between transactions. Prisma uses
prepared statements by default, which can surface as
prepared statement "s0" already exists / does not exist errors under a
transaction-mode pooler. Treat PgBeam like PgBouncer in transaction mode: tell
Prisma not to keep prepared statements across pooled connections by adding
pgbouncer=true to the connection string.
DATABASE_URL="postgresql://user:pass@abc.proxy.pgbeam.app:5432/mydb?connection_limit=5&pgbouncer=true"Or switch the project to session pool mode if you rely on session-level features. See Connection Pooling.
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:
DATABASE_URL="postgresql://user:pass@db.example.com:5432/mydb" npx prisma migrate deployThis applies to both prisma migrate deploy (production) and
prisma migrate dev (development).
Caching with Prisma
Prisma Client queries (recommended)
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 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:
// 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=1m0s swr=30sCommon issues
| Issue | Cause | Fix |
|---|---|---|
| "Too many connections" on startup | Prisma pool too large | Add ?connection_limit=5 to DATABASE_URL |
| Prepared statement errors | Using transaction pool mode | Switch to session pool mode, or avoid prepared statements |
| Migrations fail through PgBeam | Advisory locks not supported in transaction mode | Run migrations against origin directly |
| Stale data after writes | Cache returning old results | Use noCache annotation or disable cache for that query shape |
Further reading
- Connection Pooling: Pool modes and sizing guidance
- Caching: How PgBeam caching works, TTL, and SWR
- Read Replicas: Replica setup and routing