Skip to main content
Cal.com uses PostgreSQL as its primary database. This guide covers database setup, migrations, connection pooling, and optimization.

Requirements

  • PostgreSQL: Version 13 or higher
  • Storage: Minimum 20GB, recommended 100GB+ for production
  • Memory: Minimum 2GB RAM allocated to PostgreSQL
  • Connection Limit: Adjust based on your deployment scale

Database Setup

Local PostgreSQL Installation

Ubuntu/Debian

macOS

Windows

Download from postgresql.org and follow the installer.

Create Database

Connection String Format

PostgreSQL connection strings follow this format:
Examples:

Environment Configuration

Add to your .env file:

Migrations

Cal.com uses Prisma for database schema management and migrations.

Initial Setup

For a new database, run migrations to create all tables:

Migration Commands

Migration Best Practices

  • Always backup your database before running migrations in production
  • Test migrations in staging environment first
  • Use db-deploy (not db-migrate) in production
  • Never run db-reset in production (destroys all data)
The Docker start.sh script automatically runs migrations on container startup:

Schema Location

The Prisma schema is located at:

Migration Directory

Migration files are stored in:

Connection Pooling

Why Use Connection Pooling?

Connection poolers like PgBouncer help:
  • Reduce database connection overhead
  • Handle high-concurrency workloads
  • Manage connection limits efficiently
  • Improve application performance

PgBouncer Setup

Using Docker

Configuration

Update your .env to use PgBouncer:
DATABASE_DIRECT_URL must point to the actual database (not pooler) for migrations to work correctly.

Managed Pooling Services

Many providers offer built-in connection pooling:

Supabase

Railway

Railway automatically provides both pooled and direct connections.

Neon

Managed Database Providers

Railway

  1. Create a new PostgreSQL database in Railway
  2. Copy the connection string from Railway dashboard
  3. Add to .env:
Railway PostgreSQL Guide

Render

  1. Create a new PostgreSQL database in Render
  2. Get external connection string
  3. Configure:
Render PostgreSQL Docs

Supabase

  1. Create a new Supabase project
  2. Get connection strings from Settings > Database
  3. Use pooled connection for app, direct for migrations:

Neon

  1. Create a Neon project
  2. Get pooled and direct connection strings
  3. Configure:
Neon Quickstart

Amazon RDS

  1. Create RDS PostgreSQL instance
  2. Configure security groups for access
  3. Get endpoint from RDS console:

SSL Configuration

Requiring SSL

Self-Signed Certificates

For platforms like Heroku with self-signed certs:
Only use sslmode=no-verify when you trust the network and database provider.

SSL Modes

  • disable: No SSL
  • prefer: Try SSL, fallback to non-SSL
  • require: Require SSL, but don’t verify certificates
  • verify-ca: Require SSL and verify certificate
  • verify-full: Require SSL, verify certificate and hostname

Database Optimization

Indexes

Cal.com’s schema includes optimized indexes. Monitor slow queries:

Connection Limits

Adjust PostgreSQL connection limits in postgresql.conf:

Vacuum and Analyze

Enable auto-vacuum for maintenance:

Backup Strategies

pg_dump Backup

Continuous Archiving (WAL)

For point-in-time recovery, enable WAL archiving:

Managed Backups

Most managed providers offer automatic backups:
  • Supabase: Daily backups with point-in-time recovery
  • Railway: Automatic daily backups
  • Render: Daily backups included
  • RDS: Automated backups with configurable retention

Database Management Tools

Prisma Studio

Visual database browser included with Cal.com:
Prisma Studio is available in the Docker Compose setup at port 5555. Remove this service in production.

pgAdmin

Full-featured PostgreSQL management:

psql CLI

Connect directly to your database:

Docker Compose Database

The default docker-compose.yml includes PostgreSQL:
Change default credentials in production:

Separate Databases

Insights Database

For analytics workload isolation:

SAML Database (Enterprise)

For SAML SSO data:
Create the SAML database:

Troubleshooting

Connection Refused

Solutions:
  • Verify PostgreSQL is running: sudo systemctl status postgresql
  • Check port: sudo netstat -plnt | grep 5432
  • Review pg_hba.conf for connection permissions

Too Many Connections

Solutions:
  • Implement connection pooling (PgBouncer)
  • Increase max_connections in PostgreSQL
  • Check for connection leaks in application

Migration Failures

Solutions:
  • Use DATABASE_DIRECT_URL (not pooled connection)
  • Check database permissions
  • Review migration logs: yarn workspace @calcom/prisma db-migrate status
  • Manually resolve conflicts in failed migrations

Permission Denied

Solution (PostgreSQL 15+):

Authentication Failed

Solutions:
  • Verify credentials in DATABASE_URL
  • URL-encode special characters in password
  • Check pg_hba.conf authentication method (md5/scram-sha-256)

Performance Monitoring

Query Statistics

Enable pg_stat_statements extension:

Connection Monitoring

Production Checklist

  • Use PostgreSQL 13 or higher
  • Configure strong database credentials
  • Enable SSL connections (sslmode=require)
  • Set up connection pooling (PgBouncer or managed)
  • Configure DATABASE_URL and DATABASE_DIRECT_URL
  • Run migrations with db-deploy
  • Enable automated backups
  • Configure backup retention policy
  • Set up monitoring and alerts
  • Optimize PostgreSQL configuration for your workload
  • Plan for database scaling (read replicas, etc.)
  • Document recovery procedures
  • Test backup restoration process

Next Steps

  • Review Configuration for database-related environment variables
  • See Docker Setup for containerized database deployment
  • Check Deployment for platform-specific database configurations