Prisma Deployment — Deploying Prisma to Production
In this tutorial, you will learn about Prisma Deployment. We cover key concepts, practical examples, and best practices to help you master this topic.
Deploying Prisma to production requires careful management of database migrations, connection pooling, client configuration for serverless or containerized environments, and performance monitoring.
What You'll Learn
By the end of this lesson you will run migrations safely in production, configure Prisma for serverless and container deployments, optimize connection pooling, enable query logging for monitoring, and troubleshoot common production issues.
Why It Matters
Database code that works in development can fail in production due to connection limits, cold starts, Migration conflicts, and performance issues. Proper deployment configuration prevents downtime and data loss.
Real-World Use
DodaZIP deploys Prisma in Docker containers on AWS ECS. Migrations run as a separate init container before the app starts. Connection pooling uses PgBouncer to handle hundreds of concurrent connections.
Production Migrations
Run migrations safely in production.
# NEVER run `prisma migrate dev` in production
# Use `prisma migrate deploy` instead
# Deploy command
npx prisma migrate deploy
# In Docker entrypoint:
#!/bin/bash
echo "Running database migrations..."
npx prisma migrate deploy
echo "Generating Prisma Client..."
npx prisma generate
echo "Starting application..."
node dist/server.js
// deploy.ts
// Production migration script
async function runMigrations() {
console.log('Starting production migration...');
// Backup check
if (!process.env.DATABASE_URL) {
throw new Error('DATABASE_URL is required');
}
try {
// migrate deploy only applies pending migrations
const { execSync } = require('child_process');
execSync('npx prisma migrate deploy', { stdio: 'inherit' });
execSync('npx prisma generate', { stdio: 'inherit' });
console.log('Migrations applied successfully');
} catch (error) {
console.error('Migration failed:', error);
process.exit(1);
}
}
# production_migrations.py
# Production migration checklist
def production_migration_checklist():
print("Production Migration Checklist:")
print()
print("Before deployment:")
print(" [ ] Backup the database")
print(" [ ] Review migration SQL")
print(" [ ] Test on staging with production data copy")
print(" [ ] Run `prisma migrate status` to confirm pending")
print()
print("During deployment:")
print(" [ ] Run `prisma migrate deploy`")
print(" [ ] Run `prisma generate`")
print(" [ ] Verify migration applied successfully")
print()
print("After deployment:")
print(" [ ] Run health checks")
print(" [ ] Monitor error rates")
print(" [ ] Verify queries work correctly")
production_migration_checklist()
Connection Management
Configure Prisma for production database connections.
// Production Prisma Client configuration
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
// Log only errors in production
log: ['error'],
// Connection pool configuration
// Default: pool connections = num_cpus * 2 + 1
// Configure via DATABASE_URL query params
// ?connection_limit=5&pool_timeout=10
// For serverless, use Data Proxy
// datasource db {
// provider = "postgresql"
// url = env("DATABASE_URL")
// // Enable for serverless
// // directUrl = env("DIRECT_DATABASE_URL")
// }
});
export { prisma };
# Connection pool configuration
# PostgreSQL connection string with pool settings
DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=10&pool_timeout=10"
# For PgBouncer (transaction mode):
DATABASE_URL="postgresql://user:pass@pgbouncer:6432/db?pgbouncer=true&connection_limit=5"
# For serverless (Prisma Data Proxy):
DATABASE_URL="prisma://aws-us-east-1.prisma-data.com/v1/abc123"
# connection_config.py
# Connection configuration patterns
def connection_config():
print("Connection Configuration Patterns:")
print()
print("Traditional server:")
print(" - Pool connections: 10-20 per node")
print(" - connection_limit in URL")
print(" - Works for most applications")
print()
print("Container/Docker:")
print(" - connection_limit = (num_cpus * 2) + 1")
print(" - One PrismaClient per container")
print()
print("Serverless (Lambda, Cloud Functions):")
print(" - Use Prisma Data Proxy")
print(" - OR use directUrl with connection pooling")
print(" - PrismaClient in global scope (reuse)")
print()
print("PgBouncer (connection pooling):")
print(" - Add ?pgbouncer=true to connection string")
print(" - Set pool_timeout for queue management")
connection_config()
Serverless Deployment
Optimize Prisma for serverless environments.
// lib/prisma.serverless.ts
import { PrismaClient } from '@prisma/client';
// In serverless, reuse PrismaClient across invocations
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: ['error'],
// Serverless-specific options
datasources: {
db: {
url: process.env.DIRECT_DATABASE_URL, // Direct connection
},
},
});
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
// Handle connection management
process.on('beforeExit', async () => {
await prisma.$disconnect();
});
# Prisma Schema for serverless
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") # Data Proxy URL
directUrl = env("DIRECT_DATABASE_URL") # Direct database URL
}
# serverless.py
# Serverless deployment patterns
def serverless_patterns():
print("Serverless Deployment Patterns:")
print()
print("Challenges:")
print(" - Cold starts (Prisma Query Engine binary)")
print(" - Connection limits (many concurrent functions)")
print(" - Ephemeral filesystem (no local query engine)")
print()
print("Solutions:")
print(" 1. Prisma Data Proxy (serverless gateway)")
print(" 2. PgBouncer for connection pooling")
print(" 3. Global PrismaClient reuse")
print(" 4. Minimal binary targets in generator")
serverless_patterns()
Performance Optimization
Optimize Prisma queries for production.
# performance.py
# Performance optimization tips
def performance_tips():
print("Prisma Performance Optimization:")
print()
print("1. Use select instead of include")
print(" - Only fetch fields you need")
print(" - select is faster than include")
print()
print("2. Add database indexes")
print(" - Index columns used in where, orderBy")
print(" - Use @@index for composite indexes")
print()
print("3. Batch operations")
print(" - Use createMany instead of loop + create")
print(" - Use updateMany for bulk updates")
print()
print("4. Raw queries for complex operations")
print(" - Full-text search, window functions")
print(" - Complex aggregations")
print()
print("5. Enable query logging")
print(" - Log slow queries (> 100ms)")
print(" - Monitor query patterns")
performance_tips()
Common Mistakes
Running migrate dev in production: migrate dev is for development. It can reset the database. Always use migrate deploy in production.
Insufficient Connection Pool: The default connection pool may not suffice for high-traffic applications. Add PgBouncer or increase pool size.
Cold start issues in serverless: Prisma downloads the Query Engine binary on cold starts. Use Data Proxy or include the binary in the deployment package.
Not monitoring query performance: Slow queries can degrade database performance. Enable logging at the error level and monitor query durations.
Skipping migration testing: Always test migrations against a staging database with production-like data before deploying.
Practice Questions
What command runs migrations in production?
npx prisma migrate deploy. Never usemigrate devin production.How do you handle connection pooling for Prisma in production? Use PgBouncer or configure connection limits in the DATABASE_URL query parameters.
What is the Prisma Data Proxy? A serverless gateway that handles connection pooling and query engine management.
How do you optimize Prisma queries for performance? Use select (not include), add indexes, batch operations, and use raw queries for complex workloads.
Challenge: Create a production deployment plan for a Prisma application including migration Strategy, connection management, serverless configuration, and performance monitoring.
FAQ
Mini Project
Create a deployment configuration for a Prisma application including a Dockerfile with migration and generation steps, connection pooling setup, and serverless configuration.
def deployment_plan():
print("Production Deployment Plan:")
print()
print("Dockerfile:")
print(" FROM node:20-alpine")
print(" WORKDIR /app")
print(" COPY . .")
print(" RUN npm ci")
print(" RUN npx prisma generate")
print(" CMD [\"./entrypoint.sh\"]")
print()
print("entrypoint.sh:")
print(" npx prisma migrate deploy")
print(" node dist/server.js")
print()
print("Database:")
print(" - PgBouncer for connection pooling")
print(" - 20 connections per container")
print(" - Connection timeout: 10s")
deployment_plan()
What's Next
Next: Prisma Project for the capstone project.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro