Skip to main content
Paperclip uses PostgreSQL via Drizzle ORM. Choose from embedded PostgreSQL, local Docker, or hosted providers.

Database Modes

Three deployment options:
  1. Embedded PostgreSQL - Zero config, auto-managed (default)
  2. Local PostgreSQL - Docker Compose for development
  3. Hosted PostgreSQL - Supabase, AWS RDS, etc. for production

Embedded PostgreSQL

The simplest option - no setup required.

How It Works

  1. Leave DATABASE_URL unset
  2. Server auto-starts embedded PostgreSQL
  3. Data persists in ~/.paperclip/instances/default/db/

Configuration

Data directory:
Data location: $PAPERCLIP_HOME/instances/$PAPERCLIP_INSTANCE_ID/db/ Custom port (if default 54329 conflicts):

Reset Embedded Database

Database recreates automatically on startup.

When to Use

  • ✅ Local development
  • ✅ Testing and demos
  • ✅ Single-machine deployments
  • ❌ High-traffic production
  • ❌ Multi-instance deployments

Local PostgreSQL (Docker)

For development with a full PostgreSQL server.

Setup

Start PostgreSQL:
This starts PostgreSQL 17 on localhost:5432. Set connection string:
.env:
Push schema:
Start server:

docker-compose.yml

Included in the repo:

When to Use

  • ✅ Team development
  • ✅ Testing migrations
  • ✅ Matching production setup locally
  • ❌ Quick local experiments (use embedded instead)

Hosted PostgreSQL

For production deployments.

Supabase

1. Create project:
  • Visit database.new
  • Create a new project
  • Wait for provisioning (~2 minutes)
2. Get connection string:
  • Go to Project Settings > Database > Connection string
  • Copy Connection pooling URL (port 6543)
3. Configure Drizzle for pooling: Edit packages/db/src/client.ts:
4. Set environment variable:
5. Push schema (use direct connection):
Supabase free tier:
  • 500 MB database storage
  • 200 concurrent connections
  • Projects pause after 1 week of inactivity

AWS RDS

1. Create RDS instance:
2. Configure security group:
  • Allow inbound PostgreSQL (port 5432) from your deployment
3. Set connection string:

Other Providers

Any PostgreSQL 17+ provider works: General setup:
  1. Create PostgreSQL 17+ instance
  2. Get connection string
  3. Set DATABASE_URL
  4. Push schema with drizzle-kit push

Migrations

Automatic Migrations

On startup, Paperclip automatically runs migrations if:
  • Database is empty (fresh install)
  • PAPERCLIP_MIGRATION_PROMPT=never is set

Manual Migrations

Generate migration from schema changes:
This reads packages/db/src/schema/*.ts and generates SQL in packages/db/src/migrations/. Apply migrations:
Or use drizzle-kit push to sync schema directly (for development):

Migration Workflow

1. Edit schema:
2. Export from schema index:
3. Generate migration:
4. Review generated SQL:
5. Apply migration:
6. Verify TypeScript compiles:

Migration Files

Migrations are stored in packages/db/src/migrations/:
Each migration is a timestamped SQL file that modifies the schema.

Database Schema

Core tables:
  • companies - Company entities
  • agents - AI agents
  • tasks - Work items
  • issues - Issue tracking
  • goals - Company goals
  • projects - Project organization
  • agent_api_keys - Agent authentication
  • company_secrets - Secret storage
  • company_secret_versions - Secret versioning
  • activity_log - Audit trail
  • authUsers - User authentication
  • authSessions - Session management
  • instance_user_roles - Instance permissions
  • company_memberships - Company access
Full schema: packages/db/src/schema/

Connection Management

Connection Pooling

For hosted databases, use connection pooling: Supabase:
Disable prepared statements:

Connection Limits

PostgreSQL default: 100 connections Paperclip uses 1-2 connections per server instance. For high-traffic deployments:
  • Use connection pooling (PgBouncer, Supabase Pooler)
  • Scale PostgreSQL instance
  • Use read replicas for read-heavy workloads

Backup and Restore

Backup Embedded Database

Or manually:

Backup External Database

Restore

Embedded:
External:

Troubleshooting

Connection Refused

Check PostgreSQL is running:
Check connection string:
Test connection:

Migration Failures

Reset and retry:

Too Many Connections

Use connection pooling:
  • Supabase: Use port 6543
  • Deploy PgBouncer
  • Upgrade database instance
Check active connections:

Slow Queries

Enable query logging:
Analyze query performance:

Production Checklist

1

Use hosted PostgreSQL

Don’t use embedded PostgreSQL in production.
2

Enable connection pooling

Use pooled connections (port 6543 for Supabase).
3

Set up automated backups

Use provider backups or pg_dump cron jobs.
4

Monitor connections

Alert on connection count approaching limits.
5

Test disaster recovery

Verify backup restoration works.
6

Use migrations in CI/CD

Run pnpm db:migrate in deployment pipeline.

Next Steps

Configuration

Configure database connection and runtime options

Security

Secure database credentials and access