Deploying Prisma
Prisma Intermediate/Advanced
Chapter 9 ยท Deploying Prisma
Everything so far has run on a laptop. Deploying a Prisma app raises a few specific questions: when the client gets generated, how the running app and the migration step find the database, how many connections each environment opens, and what changes on serverless and edge platforms. This chapter works through them, then takes an honest look at Prisma's own hosted products.
Environments and Their Settings
| Environment | Database | Migrations run by |
|---|---|---|
| Development | Local (often Docker) | You, with migrate dev |
| Test / CI | Throwaway (Chapter 5) | CI, with migrate deploy |
| Staging | Production-like copy | The deploy pipeline |
| Production | Real data | The deploy pipeline, once per release (Chapter 8) |
Keep connection strings in environment variables set by the platform, never in the repository. Commit a
.env.example listing the variable names with placeholder values, and add .env to
.gitignore.
Two connection strings
In Prisma 7 the running app and the CLI connect separately: the app through its driver adapter, the CLI
through the datasource.url in the config file. That makes it natural to give each its own URL
— useful as soon as a connection pooler sits in front of the database, because migrations need a
direct connection:
Building: Generate the Client Explicitly
Since Prisma Fundamentals, the client has been generated into your own folder (generated/prisma).
That folder is build output: add it to .gitignore and generate it during every build. Don't rely on
it appearing as a side effect of installing packages or running migrations — in Prisma 7, migrate commands
don't generate it for you.
binaryTargets settings and "engine not found" errors in Docker. Prisma 7's
prisma-client generator is written in TypeScript and talks to the database through your driver
adapter, so that whole class of deployment problem is gone.
A Docker image
The migrations folder and config are copied so the same image can run the release step. Note that
npm ci --omit=dev skips dev dependencies: if prisma (the CLI) is a dev dependency, run
migrations from the build image or a separate job instead. Adjust prisma.config.ts if your project
uses the prisma7.config.ts name.
Shutting down cleanly
Platforms send SIGTERM before stopping a container. Disconnecting once, at shutdown, is
good practice; disconnecting after each request is not — Prisma's docs warn it slows every request down.
Long-Running Servers vs. Serverless
| Long-running server | Serverless functions | |
|---|---|---|
| Client instances | One per process, for its whole life | One per function instance; many can exist at once |
| Where to create the client | At startup (lib/prisma.ts) | Outside the handler, so warm instances reuse it |
| Pool size | Chapter 7's budget | Start at 1 per instance without an external pooler |
| Main risk | Too many processes × pool size | A traffic spike creates hundreds of instances and exhausts the database |
| Usual fix | Tune pool sizes | An external pooler (PgBouncer or a managed equivalent) |
PrismaClient on each reload and leak connections. Prisma's documented fix is to keep the client on
globalThis in development, since global variables survive reloads.
Edge Runtimes
Edge platforms such as Cloudflare Workers and Vercel Edge Functions run JavaScript close to users, but they aren't Node.js and often can't open ordinary TCP database connections. What works depends on the driver:
| Driver | How it connects | Works on |
|---|---|---|
| Neon serverless, PlanetScale serverless | HTTP | Cloudflare Workers and Vercel Edge |
| libSQL / Turso | HTTP | Cloudflare Workers and Vercel Edge |
| Cloudflare D1 | Cloudflare binding | Cloudflare Workers only |
node-postgres (pg) | TCP via Cloudflare's connect() | Cloudflare Workers only, not Vercel Edge |
Because Prisma 7 always uses a driver adapter, running at the edge is mostly a matter of choosing an edge-compatible driver and its adapter. Check your platform's and Prisma's current docs before committing: this area changes often.
Prisma's Hosted Products: an Honest Look
Prisma (the company) sells hosted services alongside the free, open-source ORM. You don't need any of them to use Prisma ORM.
| Product | What it is | Consider it when | Trade-offs |
|---|---|---|---|
| Prisma Postgres | A managed PostgreSQL database | You want a database with pooling built in and little setup | Compare price, region and backup options with other managed Postgres providers |
| Prisma Accelerate | A hosted connection pool with optional query caching | Serverless or edge apps exhausting connections; read-heavy pages | An extra network hop and dependency; cached data can be stale |
Weigh them the way you would any vendor: what problem it solves for your app, what it costs at your traffic, and how hard it would be to leave. A self-managed PgBouncer, or your cloud provider's own pooler, solves the connection problem without tying you to one vendor. Product names, features and pricing change — check Prisma's current documentation rather than relying on this summary.
Hands-On Exercises
Set up the blog API's configuration for two URLs (pooled and direct), a .env.example, .gitignore entries and build/release/start scripts. Explain which process uses which URL.
A serverless version of the API works in testing but fails with "too many connections" during a traffic spike. Diagnose it and list the fixes in order of preference.
๐ View solutionWrite a short decision note choosing where to deploy the blog API (a single container, serverless, or edge) for a site with readers mostly in one country and a PostgreSQL database in the same region. Justify it using this chapter.
๐ View solutionChapter 9 Quick Reference
- Secrets in environment variables; commit
.env.example, ignore.envandgenerated/ - App uses the adapter's URL (pooled); CLI uses the config's
datasource.url(direct) - Build runs
prisma generate; release runsmigrate deployonce; start runs the app - Prisma 7: no engine binaries, no
binaryTargetsheadaches $disconnect()once onSIGTERM, never per request- Serverless: client outside the handler, pool of 1, external pooler for spikes
- Edge: pick an edge-compatible driver + adapter; mind the distance to the database
- Hosted products (Prisma Postgres, Accelerate) are optional; compare them like any vendor