Skip to content

Deploying Cal.com

Introduction

Cal.com (formerly Calendly alternative) is a powerful open-source scheduling and calendar platform that enables individuals, teams, and organizations to streamline appointment booking, meeting coordination, and time management. Built with modern web technologies including Next.js, Prisma, and tRPC, Cal.com offers a flexible, privacy-focused alternative to proprietary scheduling solutions with full control over your data and infrastructure.

Deploying Cal.com on Klutch.sh provides a production-ready, scalable infrastructure for your scheduling platform with automated Docker deployments, persistent storage for user data and configurations, secure PostgreSQL database integration, custom domain support with automatic SSL/TLS certificates, and enterprise-grade reliability. Whether you’re building a personal booking page, team scheduling system, or white-label scheduling solution for clients, Klutch.sh simplifies the deployment process and ensures your Cal.com instance is always available and performant.

This comprehensive guide walks you through deploying Cal.com on Klutch.sh using a Dockerfile, configuring PostgreSQL database connections, setting up persistent volumes for uploaded files and assets, managing critical environment variables for authentication and integrations, configuring calendar providers (Google Calendar, Microsoft Outlook, Apple Calendar), and implementing production best practices for a secure, scalable scheduling platform that handles thousands of bookings.


Prerequisites

Before you begin deploying Cal.com on Klutch.sh, ensure you have:

  • A Klutch.sh account (sign up here)
  • A GitHub repository for your Cal.com deployment configuration
  • A PostgreSQL database instance (required for Cal.com)
  • Basic understanding of Docker containers and environment variables
  • (Optional) OAuth credentials for calendar integrations (Google, Microsoft, Apple)
  • (Optional) SMTP server credentials for email notifications
  • Access to the Klutch.sh dashboard

Understanding Cal.com Architecture

Cal.com consists of several key components that work together to provide a complete scheduling solution:

  • Next.js Frontend: React-based application serving the booking interface, admin dashboard, and public booking pages
  • tRPC API Layer: Type-safe API handling all business logic, booking management, and data operations
  • Prisma ORM: Database abstraction layer managing PostgreSQL connections and migrations
  • PostgreSQL Database: Primary data store for users, bookings, calendars, availability, and integrations
  • Email Service: SMTP integration for booking confirmations, reminders, and notifications
  • Calendar Integrations: OAuth connections to Google Calendar, Microsoft Outlook, Apple Calendar, and CalDAV providers
  • Payment Processing: Optional Stripe integration for paid bookings and subscriptions
  • Storage: File storage for user avatars, branding assets, and attachments

When deployed on Klutch.sh, Cal.com automatically detects your Dockerfile and builds a container image that includes all necessary components. The platform manages HTTP traffic routing, SSL certificates, environment variable management, and provides persistent storage options for uploaded files and assets.


Project Structure

A minimal repository structure for deploying Cal.com on Klutch.sh:

calcom-deployment/
├── Dockerfile
├── .dockerignore
├── .gitignore
├── .env.example
└── README.md

This simple structure allows Klutch.sh to automatically detect and build your Cal.com container. The official Cal.com Docker image comes pre-packaged with all necessary code, dependencies, and build artifacts, so you don’t need to include the source code in your repository.


Creating Your Dockerfile

Klutch.sh automatically detects a Dockerfile in the root directory of your repository. Create a Dockerfile that uses the official Cal.com image as the base:

FROM calcom/cal.com:latest
# Expose the default Cal.com port
EXPOSE 3000
# The official image includes a startup script
# that handles database migrations and service startup
CMD ["npm", "start"]

Option 2: Production Dockerfile with Health Checks

FROM calcom/cal.com:latest
# Set working directory
WORKDIR /calcom
# Expose the application port
EXPOSE 3000
# Add health check for monitoring
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
# Start Cal.com with automatic database migrations
CMD ["npm", "run", "start"]

Option 3: Custom Dockerfile with Build Optimizations

FROM calcom/cal.com:latest
# Install additional system dependencies if needed
RUN apt-get update && apt-get install -y \
curl \
wget \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /calcom
# Copy custom configuration files (optional)
# COPY ./custom-config /calcom/config
# Expose the application port
EXPOSE 3000
# Health check for production monitoring
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
# Run database migrations and start the application
CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]

Important Notes:

  • Cal.com listens on port 3000 internally by default
  • Klutch.sh will route external HTTP traffic to port 3000 in your container
  • The container includes the Next.js application, API routes, and scheduling engine
  • Database migrations should run automatically on startup
  • The official image is optimized for production deployments

Deploying to Klutch.sh

    1. Create Your Repository

      Create a new GitHub repository and add your Dockerfile:

      Terminal window
      mkdir calcom-deployment
      cd calcom-deployment
      # Create Dockerfile
      cat > Dockerfile << 'EOF'
      FROM calcom/cal.com:latest
      WORKDIR /calcom
      EXPOSE 3000
      HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
      CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
      CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]
      EOF
      # Create .dockerignore
      cat > .dockerignore << 'EOF'
      node_modules
      .next
      .env
      .env.local
      .git
      .DS_Store
      dist
      EOF
      # Create .gitignore
      cat > .gitignore << 'EOF'
      node_modules/
      .env
      .env.local
      .DS_Store
      .next/
      dist/
      EOF
      # Initialize git and push
      git init
      git add .
      git commit -m "Initial Cal.com deployment setup"
      git remote add origin https://github.com/YOUR_USERNAME/calcom-deployment.git
      git push -u origin main
    2. Set Up PostgreSQL Database

      Cal.com requires a PostgreSQL database. You can either:

      Create a database for Cal.com:

      CREATE DATABASE calcom;
      CREATE USER calcom_user WITH PASSWORD 'your-strong-secure-password';
      GRANT ALL PRIVILEGES ON DATABASE calcom TO calcom_user;

      Note your connection details:

      • Host: Your database hostname
      • Port: 5432 (or 8000 if deployed on Klutch.sh with TCP traffic)
      • Database: calcom
      • Username: calcom_user
      • Password: your-strong-secure-password
    3. Access the Klutch.sh Dashboard

      Navigate to klutch.sh/app and log in to your account.

    4. Create a New Project

      • Click “New Project” in the dashboard
      • Enter a project name (e.g., “Scheduling Platform”)
      • Select your preferred region for deployment
    5. Create a New Application

      • Within your project, click “New App”
      • Name your application (e.g., “Cal.com”)
      • Connect your GitHub repository containing the Dockerfile
    6. Configure Build Settings

      Klutch.sh automatically detects the Dockerfile in your repository root. If your Dockerfile is in a subdirectory, specify the build context path in the dashboard.

    7. Set Up Persistent Storage

      Cal.com benefits from persistent storage for user uploads and cache:

      • In the app settings, navigate to the “Volumes” section
      • Click “Add Volume”
      • Set the mount path to /calcom/.next/cache
      • Set the volume size (recommended: 5GB minimum)
      • Click “Add” to attach the volume

      Optionally add another volume for user uploads:

      • Click “Add Volume” again
      • Set the mount path to /calcom/public/uploads
      • Set the volume size (recommended: 10GB minimum for production)
    8. Configure Environment Variables

      In the app settings, add the following required environment variables:

      Essential Database Variables:

      Terminal window
      DATABASE_URL=postgresql://calcom_user:your-password@your-db-host:5432/calcom

      For databases deployed on Klutch.sh with TCP traffic:

      Terminal window
      DATABASE_URL=postgresql://calcom_user:your-password@your-db-app.klutch.sh:8000/calcom

      Application Configuration:

      Terminal window
      NEXTAUTH_URL=https://your-app-name.klutch.sh
      NEXTAUTH_SECRET=your-random-secret-key-min-32-characters
      CALENDSO_ENCRYPTION_KEY=your-encryption-key-min-32-characters

      Email Configuration (SMTP):

      Terminal window
      EMAIL_FROM=noreply@yourdomain.com
      EMAIL_SERVER_HOST=smtp.sendgrid.net
      EMAIL_SERVER_PORT=587
      EMAIL_SERVER_USER=apikey
      EMAIL_SERVER_PASSWORD=your-sendgrid-api-key

      Optional Google Calendar Integration:

      Terminal window
      GOOGLE_API_CREDENTIALS={"web":{"client_id":"your-client-id","client_secret":"your-client-secret","redirect_uris":["https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback"]}}

      Optional Payment Integration (Stripe):

      Terminal window
      STRIPE_PRIVATE_KEY=sk_live_your_stripe_key
      STRIPE_PUBLIC_KEY=pk_live_your_stripe_key
      STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
      PAYMENT_FEE_PERCENTAGE=0.005
      PAYMENT_FEE_FIXED=10

      Security Best Practice: Always use the “Secret” checkbox for sensitive values like database passwords, API keys, and encryption keys.

    9. Configure Traffic Settings

      • In the “Networking” section, select HTTP as the traffic type
      • Set the internal port to 3000 (Cal.com’s default port)
      • Enable automatic HTTPS/SSL (provided by Klutch.sh)
    10. Deploy the Application

      • Review all settings
      • Click “Deploy” to start the build process
      • Klutch.sh will:
        • Clone your repository
        • Detect the Dockerfile
        • Build the container image
        • Deploy to your selected region
        • Provision persistent storage
        • Run database migrations automatically
        • Configure networking and SSL
    11. Monitor Deployment Progress

      • View real-time build logs in the dashboard
      • Wait for the deployment status to show “Running”
      • Initial startup may take 3-5 minutes as Cal.com runs database migrations and initializes services
      • Watch for successful migration messages in the logs

Once deployment completes, your Cal.com instance will be accessible at https://your-app-name.klutch.sh or your configured custom domain.


Database Configuration and Optimization

Cal.com requires PostgreSQL and benefits significantly from proper database configuration and optimization.

Connection String Format

The DATABASE_URL must follow PostgreSQL connection string format:

Terminal window
postgresql://[user]:[password]@[host]:[port]/[database]?[parameters]

Examples:

Standard PostgreSQL:

Terminal window
DATABASE_URL=postgresql://calcom_user:password123@postgres.example.com:5432/calcom?schema=public

With SSL enabled:

Terminal window
DATABASE_URL=postgresql://calcom_user:password123@postgres.example.com:5432/calcom?schema=public&sslmode=require

Klutch.sh TCP deployment:

Terminal window
DATABASE_URL=postgresql://calcom_user:password123@postgres-app.klutch.sh:8000/calcom?schema=public

Database Performance Optimization

    1. Configure Connection Pooling

      Add connection pool parameters to your DATABASE_URL:

      Terminal window
      DATABASE_URL=postgresql://user:pass@host:5432/calcom?schema=public&connection_limit=20&pool_timeout=20
    2. Add Database Indexes

      Connect to your PostgreSQL database and create performance indexes:

      -- Index for booking lookups
      CREATE INDEX idx_bookings_user_id ON "Booking"("userId");
      CREATE INDEX idx_bookings_event_type_id ON "Booking"("eventTypeId");
      CREATE INDEX idx_bookings_status ON "Booking"("status");
      CREATE INDEX idx_bookings_start_time ON "Booking"("startTime");
      -- Index for availability checks
      CREATE INDEX idx_availability_user_id ON "Availability"("userId");
      CREATE INDEX idx_availability_event_type_id ON "Availability"("eventTypeId");
      -- Index for user lookups
      CREATE INDEX idx_users_email ON "User"("email");
      CREATE INDEX idx_users_username ON "User"("username");
    3. Set Appropriate Connection Limits

      For production deployments, configure your PostgreSQL server:

      max_connections = 100
      shared_buffers = 256MB
      effective_cache_size = 1GB
      work_mem = 16MB
    4. Enable Query Logging for Debugging

      During initial setup, enable slow query logging:

      log_min_duration_statement = 1000

Database Backup Strategy

    1. Automated Daily Backups

      Set up a cron job or scheduled task:

      #!/bin/bash
      DATE=$(date +%Y%m%d_%H%M%S)
      pg_dump -h your-db-host -U calcom_user -d calcom > /backups/calcom_$DATE.sql
      # Compress the backup
      gzip /backups/calcom_$DATE.sql
      # Upload to S3 or object storage
      aws s3 cp /backups/calcom_$DATE.sql.gz s3://your-backup-bucket/calcom/
      # Delete local backups older than 7 days
      find /backups -name "calcom_*.sql.gz" -mtime +7 -delete
    2. Test Restore Procedures

      Periodically test restoring from backups:

      Terminal window
      # Download backup
      aws s3 cp s3://your-backup-bucket/calcom/calcom_20240115_120000.sql.gz .
      # Decompress
      gunzip calcom_20240115_120000.sql.gz
      # Restore to test database
      psql -h test-db-host -U calcom_user -d calcom_test < calcom_20240115_120000.sql
    3. Point-in-Time Recovery

      For critical deployments, enable PostgreSQL WAL archiving for point-in-time recovery.


Environment Variables Reference

Required Variables

VariableDescriptionExample
DATABASE_URLPostgreSQL connection string (required)postgresql://user:pass@host:5432/calcom
NEXTAUTH_URLFull URL where Cal.com is hostedhttps://cal.example.com
NEXTAUTH_SECRETRandom secret for session encryption (min 32 chars)openssl rand -base64 32
CALENDSO_ENCRYPTION_KEYEncryption key for sensitive data (32 chars)openssl rand -hex 16

Email Configuration

VariableDescriptionExample
EMAIL_FROMSender email addressnotifications@example.com
EMAIL_SERVER_HOSTSMTP server hostnamesmtp.sendgrid.net
EMAIL_SERVER_PORTSMTP server port587
EMAIL_SERVER_USERSMTP usernameapikey
EMAIL_SERVER_PASSWORDSMTP password/API keySG.xxxxx

Calendar Integrations

VariableDescription
GOOGLE_API_CREDENTIALSJSON credentials for Google Calendar OAuth
MS_GRAPH_CLIENT_IDMicrosoft Graph API client ID
MS_GRAPH_CLIENT_SECRETMicrosoft Graph API client secret
APPLE_CALENDAR_CLIENT_IDApple Calendar client ID
APPLE_CALENDAR_CLIENT_SECRETApple Calendar client secret

Payment Integration (Stripe)

VariableDescription
STRIPE_PRIVATE_KEYStripe secret key
STRIPE_PUBLIC_KEYStripe publishable key
STRIPE_WEBHOOK_SECRETStripe webhook signing secret
PAYMENT_FEE_PERCENTAGEPlatform fee percentage (0.005 = 0.5%)
PAYMENT_FEE_FIXEDFixed fee in cents (10 = $0.10)

Optional Advanced Configuration

VariableDescriptionDefault
NEXT_PUBLIC_WEBAPP_URLPublic-facing URLValue of NEXTAUTH_URL
NEXT_PUBLIC_WEBSITE_URLMarketing website URLValue of NEXTAUTH_URL
NEXT_PUBLIC_APP_URLApp URL for redirectsValue of NEXTAUTH_URL
CRON_API_KEYSecret key for cron endpointsRandom string
DAILY_API_KEYDaily.co API key for video-
ZOOM_CLIENT_IDZoom OAuth client ID-
ZOOM_CLIENT_SECRETZoom OAuth client secret-

Setting Up Calendar Integrations

Cal.com’s power comes from its deep calendar integrations. Here’s how to configure the most popular providers:

Google Calendar Integration

    1. Create Google Cloud Project

      • Go to Google Cloud Console
      • Create a new project or select an existing one
      • Enable the Google Calendar API
    2. Configure OAuth Consent Screen

      • Navigate to “APIs & Services” → “OAuth consent screen”
      • Choose “External” user type
      • Fill in application name, user support email, and developer contact
      • Add scopes: https://www.googleapis.com/auth/calendar
      • Save and continue
    3. Create OAuth 2.0 Credentials

      • Go to “APIs & Services” → “Credentials”
      • Click “Create Credentials” → “OAuth client ID”
      • Application type: “Web application”
      • Add authorized redirect URI: https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback
      • Save and copy the client ID and client secret
    4. Configure Cal.com Environment Variable

      Create the JSON credentials structure:

      Terminal window
      GOOGLE_API_CREDENTIALS={"web":{"client_id":"123456789.apps.googleusercontent.com","client_secret":"your-client-secret","redirect_uris":["https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback"]}}
    5. Test Integration

      • Log into your Cal.com instance
      • Go to Settings → Integrations
      • Connect Google Calendar
      • Authorize the application
      • Verify calendar events sync correctly

Microsoft Outlook/Office 365 Integration

    1. Register Application in Azure

      • Go to Azure Portal
      • Navigate to “Azure Active Directory” → “App registrations”
      • Click “New registration”
      • Name: “Cal.com Scheduling”
      • Redirect URI: https://your-app-name.klutch.sh/api/integrations/office365calendar/callback
    2. Configure API Permissions

      • In your app registration, go to “API permissions”
      • Add permissions for Microsoft Graph:
        • Calendars.ReadWrite
        • Calendars.ReadWrite.Shared
        • User.Read
      • Grant admin consent
    3. Create Client Secret

      • Go to “Certificates & secrets”
      • Create a new client secret
      • Copy the secret value immediately (it won’t be shown again)
    4. Configure Environment Variables

      Terminal window
      MS_GRAPH_CLIENT_ID=your-application-client-id
      MS_GRAPH_CLIENT_SECRET=your-client-secret-value
    5. Test Integration

      • In Cal.com Settings → Integrations
      • Connect Office 365 Calendar
      • Sign in with Microsoft account
      • Grant permissions and verify sync

Custom Domain Configuration

To use your own domain (e.g., cal.yourdomain.com) with Cal.com on Klutch.sh:

    1. Add Domain in Dashboard

      • Navigate to your Cal.com app in the Klutch.sh dashboard
      • Go to “Domains” section
      • Click “Add Custom Domain”
      • Enter your domain (e.g., cal.yourdomain.com)
    2. Configure DNS Records

      Add a CNAME record in your DNS provider:

      Type: CNAME
      Name: cal
      Value: your-app-name.klutch.sh
      TTL: 3600
    3. Update Environment Variables

      Update the URL variables to use your custom domain:

      Terminal window
      NEXTAUTH_URL=https://cal.yourdomain.com
      NEXT_PUBLIC_WEBAPP_URL=https://cal.yourdomain.com
      NEXT_PUBLIC_WEBSITE_URL=https://cal.yourdomain.com
    4. Redeploy Application

      • Trigger a new deployment in the Klutch.sh dashboard to apply the environment variable changes
    5. Enable SSL/TLS

      • Klutch.sh automatically provisions and manages SSL certificates using Let’s Encrypt
      • SSL activation typically takes 5-15 minutes after DNS propagation
    6. Verify Configuration

      • Wait for DNS propagation (usually 5-15 minutes)
      • Visit https://cal.yourdomain.com
      • Verify SSL certificate is active and trusted
      • Test booking flow to ensure all redirects work correctly

For detailed domain configuration, see the Klutch.sh Custom Domains guide.


Getting Started with Cal.com

After deploying your Cal.com instance, follow these steps to set up your first event type and start accepting bookings:

Initial Setup

    1. Create Your Account

      • Navigate to https://your-app-name.klutch.sh (or your custom domain)
      • Click “Sign up” or “Get Started”
      • Enter your email address and choose a strong password
      • Verify your email (if email is configured)
      • Complete your profile with name and username
    2. Configure Your Profile

      • Go to Settings → Profile
      • Upload a profile photo
      • Set your display name and bio
      • Choose your username (this becomes your booking page URL: /username)
      • Set your timezone
    3. Connect Your Calendar

      • Go to Settings → Integrations
      • Connect your primary calendar (Google Calendar, Outlook, etc.)
      • Follow the OAuth flow to authorize access
      • Select which calendar should receive new bookings
      • Configure conflict checking to prevent double-bookings

Creating Your First Event Type

    1. Navigate to Event Types

      • From the dashboard, click “Event Types”
      • Click “New Event Type” button
    2. Configure Basic Details

      • Title: “30 Minute Meeting” (or your preferred name)
      • URL: /30min (becomes example-app.klutch.sh/username/30min)
      • Description: Describe what this meeting is for
      • Duration: 30 minutes
      • Location: Choose from:
        • Zoom (if integrated)
        • Google Meet (if using Google Calendar)
        • Microsoft Teams
        • Phone call
        • In-person address
    3. Set Your Availability

      • Click “Availability” tab
      • Set your working hours:
        • Monday-Friday: 9:00 AM - 5:00 PM
        • Set timezone for display
      • Add buffer time before/after meetings
      • Set minimum notice period (e.g., 4 hours)
      • Configure date range limits
    4. Customize Booking Questions

      • Add custom questions:
        • Name (required by default)
        • Email (required by default)
        • Phone number (optional)
        • Company name
        • Meeting purpose
        • Custom questions specific to your needs
    5. Configure Advanced Settings

      • Confirmation: Require manual confirmation or auto-confirm
      • Reminders: Set email reminders (24h, 1h before)
      • Redirect: After booking confirmation page
      • Payment: Require payment via Stripe (optional)
      • Limits: Max bookings per day
    6. Save and Test

      • Click “Save” to create the event type
      • Visit your booking page: your-app-name.klutch.sh/your-username/30min
      • Test the booking flow by creating a test booking

Sample Event Type Configurations

1. Quick 15-Minute Call

Title: Quick Chat
Duration: 15 minutes
Buffer: 5 minutes before and after
Minimum Notice: 2 hours
Location: Phone call
Auto-confirm: Yes

2. Discovery Call

Title: Discovery Call
Duration: 60 minutes
Buffer: 10 minutes before
Minimum Notice: 24 hours
Location: Zoom
Auto-confirm: No (manual confirmation)
Questions: Company name, Project description

3. Paid Consultation

Title: Expert Consultation
Duration: 45 minutes
Price: $150
Payment: Stripe (required)
Location: Google Meet
Minimum Notice: 48 hours

Team Features and Collaborative Scheduling

Cal.com supports team scheduling for organizations:

Setting Up a Team

    1. Create a Team

      • Go to Settings → Teams
      • Click “Create Team”
      • Enter team name and slug
      • Invite team members via email
    2. Configure Team Event Types

      • Create event types at the team level
      • Options:
        • Round Robin: Distribute bookings evenly
        • Collective: All members must be available
        • Managed Event: Assigned to specific members
    3. Team Availability

      • Set team working hours
      • Individual members can override with their schedules
      • System automatically finds available slots across all members
    4. Team Booking Page

      • Access at: your-app.klutch.sh/team/team-name
      • Shows all team event types
      • Displays team members and bios

Production Best Practices

Security Hardening

    1. Use Strong Secrets

      Generate cryptographically secure secrets:

      Terminal window
      # Linux/macOS
      NEXTAUTH_SECRET=$(openssl rand -base64 32)
      CALENDSO_ENCRYPTION_KEY=$(openssl rand -hex 16)
      CRON_API_KEY=$(openssl rand -base64 32)
    2. Enable Rate Limiting

      Protect against abuse by configuring rate limits in your environment:

      Terminal window
      RATE_LIMIT_ENABLED=true
      RATE_LIMIT_MAX_REQUESTS=100
      RATE_LIMIT_WINDOW_MS=60000
    3. Implement IP Allowlisting

      For admin sections, consider using Klutch.sh network policies or reverse proxy rules.

    4. Configure Content Security Policy

      Set appropriate CSP headers to prevent XSS attacks.

    5. Regular Security Updates

      Update your Dockerfile to use specific Cal.com versions:

      FROM calcom/cal.com:v3.5.0

      Then regularly update to newer stable versions and redeploy.

    6. Database Connection Security

      Always use SSL for database connections:

      Terminal window
      DATABASE_URL=postgresql://user:pass@host:5432/calcom?sslmode=require
    7. Monitor Authentication Logs

      Regularly review authentication attempts and failed login logs.

Performance Optimization

    1. Enable Next.js Output Caching

      Ensure your Dockerfile properly handles Next.js cache:

      # Leverage build cache
      ENV NEXT_TELEMETRY_DISABLED 1
    2. Configure Database Connection Pool

      Optimize database connections:

      Terminal window
      DATABASE_URL=postgresql://user:pass@host:5432/calcom?connection_limit=20&pool_timeout=20
    3. Use CDN for Static Assets

      Configure Cal.com to serve static assets from a CDN:

      Terminal window
      NEXT_PUBLIC_STATIC_CDN_URL=https://cdn.yourdomain.com
    4. Monitor Performance

      • Set up monitoring in the Klutch.sh dashboard
      • Watch CPU, memory, and database connection usage
      • Monitor booking page load times
      • Track API response times
    5. Optimize Images

      Cal.com automatically optimizes images, but ensure:

      • User avatars are reasonably sized
      • Brand assets are compressed
      • Use WebP format when possible
    6. Enable Query Caching

      Cal.com uses tRPC with built-in caching. Monitor cache hit rates.

Monitoring and Logging

    1. Application Logs

      View logs in the Klutch.sh dashboard under your app’s “Logs” section.

    2. Set Up Alerts

      Configure alerts for:

      • Application downtime
      • High error rates (500 errors)
      • Database connection failures
      • Failed payment processing
      • Email delivery failures
    3. Booking Analytics

      Cal.com includes built-in analytics:

      • Go to Insights → Analytics
      • Track:
        • Total bookings
        • Booking conversion rate
        • Popular time slots
        • Event type performance
        • Revenue (if using payments)
    4. Database Monitoring

      Monitor PostgreSQL:

      • Active connections
      • Slow queries
      • Database size growth
      • Index usage
    5. Uptime Monitoring

      Use external uptime monitoring:


Troubleshooting Common Issues

Application Won’t Start

Symptoms: Container starts but Cal.com UI is not accessible, or crashes shortly after startup

Solutions:

    1. Check logs in the Klutch.sh dashboard for error messages

    2. Verify DATABASE_URL is correctly formatted:

      Terminal window
      # Should be:
      postgresql://username:password@host:port/database
      # NOT:
      postgres://... (use 'postgresql://')
    3. Ensure database is accessible:

      Terminal window
      # For TCP on Klutch.sh, use port 8000:
      postgresql://user:pass@db-app.klutch.sh:8000/calcom
    4. Verify all required environment variables are set:

      • DATABASE_URL
      • NEXTAUTH_URL
      • NEXTAUTH_SECRET
      • CALENDSO_ENCRYPTION_KEY
    5. Check that NEXTAUTH_URL matches your actual domain (no trailing slash)

    6. Ensure database migrations completed successfully in the logs

Database Migration Errors

Symptoms: “Migration failed” or “P1001: Can’t reach database server” in logs

Solutions:

    1. Verify database connection by testing connection string:

      Terminal window
      psql "postgresql://user:pass@host:port/database"
    2. Check PostgreSQL version compatibility (Cal.com requires PostgreSQL 12+)

    3. Ensure database user has sufficient privileges:

      GRANT ALL PRIVILEGES ON DATABASE calcom TO calcom_user;
      GRANT ALL ON SCHEMA public TO calcom_user;
    4. For TCP deployments on Klutch.sh, ensure you’re using port 8000

    5. Manually run migrations if needed:

      Terminal window
      npx prisma migrate deploy

Calendar Integration Not Working

Symptoms: Can’t connect Google Calendar, bookings not syncing

Solutions:

    1. Verify OAuth credentials are correctly formatted in GOOGLE_API_CREDENTIALS

    2. Check redirect URI matches exactly:

      https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback
    3. Ensure Google Calendar API is enabled in Google Cloud Console

    4. Verify OAuth consent screen is published (not in testing mode)

    5. Check that calendar scopes are approved:

      • https://www.googleapis.com/auth/calendar
      • https://www.googleapis.com/auth/calendar.events
    6. Try disconnecting and reconnecting the integration

Email Notifications Not Sending

Symptoms: Booking confirmations and reminders not being sent

Solutions:

    1. Verify all email environment variables are set:

      • EMAIL_FROM
      • EMAIL_SERVER_HOST
      • EMAIL_SERVER_PORT
      • EMAIL_SERVER_USER
      • EMAIL_SERVER_PASSWORD
    2. Test SMTP credentials manually:

      Terminal window
      telnet smtp.sendgrid.net 587
    3. Check that EMAIL_FROM is a verified sender in your SMTP provider

    4. Review email logs in your SMTP provider dashboard

    5. Ensure firewall allows outbound connections on SMTP ports (587, 465, or 25)

    6. Try a different SMTP provider to isolate the issue

Performance Issues

Symptoms: Slow page loads, booking page timeouts

Solutions:

    1. Check resource usage in Klutch.sh dashboard:

      • CPU usage
      • Memory usage
      • Database connections
    2. Upgrade to a larger instance size if resources are constrained

    3. Optimize database performance:

      -- Check slow queries
      SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;
      -- Add missing indexes
      CREATE INDEX idx_bookings_start_time ON "Booking"("startTime");
    4. Enable connection pooling in DATABASE_URL:

      Terminal window
      ?connection_limit=20&pool_timeout=20
    5. Monitor database connection count:

      SELECT count(*) FROM pg_stat_activity;
    6. Clear Next.js cache and redeploy:

      Terminal window
      rm -rf .next/cache

Booking Conflicts

Symptoms: Double bookings, availability showing incorrectly

Solutions:

    1. Verify calendar integration is active and connected

    2. Check calendar sync status in Settings → Integrations

    3. Ensure event type has “Check for conflicts” enabled

    4. Verify timezone settings match your actual timezone

    5. Manually sync calendars:

      • Disconnect calendar integration
      • Reconnect and reauthorize
      • Wait 5 minutes for initial sync
    6. Check that working hours are set correctly in availability settings


Scaling Your Cal.com Deployment

As your booking volume grows, consider these scaling strategies:

Vertical Scaling

Increase resources for your Cal.com instance:

  • Upgrade to a larger instance type in the Klutch.sh dashboard
  • Recommended specs based on usage:
    • Small (< 100 bookings/day): 1 CPU, 2GB RAM
    • Medium (100-500 bookings/day): 2 CPU, 4GB RAM
    • Large (500-2000 bookings/day): 4 CPU, 8GB RAM
    • Enterprise (2000+ bookings/day): 8+ CPU, 16+ GB RAM

Database Scaling

  • Use managed PostgreSQL with read replicas for high traffic
  • Enable connection pooling with PgBouncer
  • Separate read and write operations
  • Implement database query caching

High Availability Setup

For mission-critical deployments:

  • Deploy multiple Cal.com instances behind a load balancer
  • Use managed PostgreSQL with automatic failover
  • Implement Redis for session storage
  • Set up monitoring and automatic restarts

Migration from Other Platforms

If you’re migrating from Calendly, Cal.com Cloud, or self-hosted Cal.com:

    1. Export Your Data

      If migrating from Cal.com Cloud:

      • Contact Cal.com support for data export
      • Receive database dump file

      If self-hosted:

      • Create PostgreSQL backup:

        Terminal window
        pg_dump -h localhost -U calcom -d calcom > calcom_backup.sql
    2. Prepare New Database

      Create a fresh PostgreSQL database on Klutch.sh or managed service.

    3. Deploy Cal.com on Klutch.sh

      Follow the deployment steps in this guide to create a new instance.

    4. Import Data

      Restore your database backup:

      Terminal window
      psql -h your-new-host -p 8000 -U calcom_user -d calcom < calcom_backup.sql
    5. Update Integrations

      Reconnect all calendar integrations:

      • Google Calendar
      • Microsoft Outlook
      • Payment providers
      • Video conferencing tools
    6. Update Environment Variables

      Ensure all API keys and secrets are transferred to new deployment.

    7. Test Thoroughly

      • Verify all event types work correctly
      • Test booking flow end-to-end
      • Confirm email notifications send
      • Check calendar sync
      • Test payments (if applicable)
    8. Update DNS

      Point your domain to the new Klutch.sh deployment.

    9. Monitor

      Watch logs and metrics for the first 24-48 hours to catch any issues.


Advanced Customization

Custom Branding

Customize Cal.com’s appearance to match your brand:

    1. Upload Brand Assets

      • Go to Settings → Appearance
      • Upload your logo
      • Upload favicon
      • Set brand color (primary color for buttons and accents)
    2. Custom CSS

      For advanced customization, inject custom CSS:

      /* Example custom styles */
      :root {
      --brand-color: #6366f1;
      --brand-text-color: #ffffff;
      }
    3. White Label Configuration

      Remove Cal.com branding (requires pro/enterprise plan):

      Terminal window
      NEXT_PUBLIC_HIDE_BRANDING=true

Webhook Integrations

Connect Cal.com to external systems via webhooks:

    1. Configure Webhooks

      • Go to Settings → Integrations → Webhooks
      • Add new webhook subscriber
      • Enter endpoint URL: https://your-api.com/webhooks/calcom
      • Select events to subscribe to:
        • BOOKING_CREATED
        • BOOKING_CANCELLED
        • BOOKING_RESCHEDULED
        • BOOKING_CONFIRMED
    2. Implement Webhook Handler

      Example Node.js webhook receiver:

      app.post('/webhooks/calcom', express.json(), (req, res) => {
      const { triggerEvent, payload } = req.body;
      switch(triggerEvent) {
      case 'BOOKING_CREATED':
      console.log('New booking:', payload.id);
      // Send to CRM, notify team, etc.
      break;
      case 'BOOKING_CANCELLED':
      console.log('Booking cancelled:', payload.id);
      // Update CRM, send internal notification
      break;
      }
      res.status(200).send('OK');
      });
    3. Secure Webhooks

      Verify webhook signatures to prevent spoofing.


Cost Optimization Tips

  • Right-size your instance: Start with smaller resources and scale up based on actual usage
  • Optimize database queries: Ensure proper indexing to reduce compute time
  • Use managed PostgreSQL free tiers: Services like Supabase offer generous free tiers for development
  • Monitor resource usage: Use Klutch.sh monitoring to identify optimization opportunities
  • Implement caching: Reduce database queries with proper caching strategies
  • Clean up old data: Archive or delete old bookings and cancelled events periodically

Example Deployment Repository

For a complete working example, reference this sample repository structure:

calcom-on-klutch/
├── Dockerfile
├── .dockerignore
├── .gitignore
├── .env.example
└── README.md

Dockerfile:

FROM calcom/cal.com:v3.5.0
WORKDIR /calcom
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]

.env.example:

Terminal window
# Database (Required)
DATABASE_URL=postgresql://username:password@host:5432/calcom?schema=public
# Application URLs (Required)
NEXTAUTH_URL=https://your-app-name.klutch.sh
NEXT_PUBLIC_WEBAPP_URL=https://your-app-name.klutch.sh
# Security (Required - Generate with: openssl rand -base64 32)
NEXTAUTH_SECRET=your-nextauth-secret-min-32-chars
CALENDSO_ENCRYPTION_KEY=your-encryption-key-32-chars
CRON_API_KEY=your-cron-api-key
# Email Configuration (Required for notifications)
EMAIL_FROM=noreply@yourdomain.com
EMAIL_SERVER_HOST=smtp.sendgrid.net
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=apikey
EMAIL_SERVER_PASSWORD=your-sendgrid-api-key
# Google Calendar (Optional)
# GOOGLE_API_CREDENTIALS={"web":{"client_id":"...","client_secret":"...","redirect_uris":["..."]}}
# Microsoft Outlook (Optional)
# MS_GRAPH_CLIENT_ID=your-ms-client-id
# MS_GRAPH_CLIENT_SECRET=your-ms-client-secret
# Stripe Payments (Optional)
# STRIPE_PRIVATE_KEY=sk_live_...
# STRIPE_PUBLIC_KEY=pk_live_...
# STRIPE_WEBHOOK_SECRET=whsec_...

README.md:

# Cal.com on Klutch.sh
Production-ready Cal.com deployment for scheduling and appointment booking.
## Quick Start
1. Clone this repository
2. Copy `.env.example` to `.env` and configure all variables
3. Set up a PostgreSQL database
4. Push to GitHub
5. Deploy on Klutch.sh following the official guide
## Required Setup
- PostgreSQL 12+ database
- SMTP credentials for email
- OAuth credentials for calendar integrations (optional)
## Support
See the full deployment guide at <a href="https://docs.klutch.sh/guides/open-source-software/cal?utm_source=docs" target="_blank">docs.klutch.sh</a>

Additional Resources


Conclusion

Deploying Cal.com on Klutch.sh provides a powerful, scalable scheduling platform without the complexity of managing infrastructure. With automatic Dockerfile detection, PostgreSQL integration, persistent storage, secure environment management, calendar provider integrations, and production-ready configurations, you can focus on building your scheduling business and serving your customers.

Whether you’re creating a personal booking page, team scheduling system, or white-label scheduling solution for clients, Cal.com on Klutch.sh offers the reliability, performance, and flexibility you need. Start accepting bookings today and streamline your appointment management with open-source scheduling software that respects your privacy and gives you complete control.

For additional help or questions, reach out to the Cal.com community or Klutch.sh support.