Skip to main content

Managed PostgreSQL

Boards works with any PostgreSQL 14+ database. This guide covers general configuration that applies to all managed PostgreSQL providers.

Connection URL Format

Configure the database connection via environment variable:

BOARDS_DATABASE_URL=postgresql://username:password@hostname:port/database?sslmode=require

URL Components

ComponentDescriptionExample
usernameDatabase userboards_user
passwordUser password (URL-encoded if contains special chars)myp%40ssword
hostnameDatabase hostdb.example.com
portPort number5432
databaseDatabase nameboards

Query Parameters

ParameterDescriptionRecommended
sslmodeSSL connection moderequire for production
connect_timeoutConnection timeout (seconds)10
application_nameIdentifies connections in pg_stat_activityboards-api

Example with all parameters:

BOARDS_DATABASE_URL=postgresql://boards:password@db.example.com:5432/boards?sslmode=require&connect_timeout=10&application_name=boards-api

SSL Configuration

Most managed providers require SSL connections. Boards supports these modes:

ModeDescription
disableNo SSL (not recommended)
requireSSL required, no certificate verification
verify-caSSL required, verify server certificate
verify-fullSSL required, verify server certificate and hostname

For providers that require certificate verification:

# Path to CA certificate
BOARDS_DATABASE_SSL_CA=/path/to/ca-certificate.crt

Connection Pooling

For high-traffic deployments, use a connection pooler like PgBouncer:

Application → PgBouncer → PostgreSQL

Many managed providers offer built-in connection pooling:

  • Supabase: Built-in PgBouncer on port 6543
  • Neon: Serverless driver with built-in pooling
  • AWS RDS: Use RDS Proxy
  • Cloud SQL: Use Cloud SQL Auth Proxy

When using pooling, adjust your connection URL to point to the pooler:

# Direct connection
BOARDS_DATABASE_URL=postgresql://user:pass@db.supabase.co:5432/postgres

# Pooled connection (recommended)
BOARDS_DATABASE_URL=postgresql://user:pass@db.supabase.co:6543/postgres

Database Setup

1. Create Database

Most providers create a default database. If you need a dedicated database:

CREATE DATABASE boards;

2. Create User (Optional)

For better security, create a dedicated user:

CREATE USER boards_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE boards TO boards_user;

3. Run Migrations

Migrations run automatically when the API starts. To run manually:

# Docker
docker compose exec api python -m boards.db.migrate

# Direct
BOARDS_DATABASE_URL=postgresql://... python -m boards.db.migrate

Performance Recommendations

Minimum Requirements

WorkloadvCPURAMStorage
Development11GB10GB
Small production24GB20GB
Medium production48GB50GB
Large production8+16GB+100GB+

Indexes

Boards creates these indexes automatically via migrations. Verify they exist for optimal performance:

-- Check existing indexes
SELECT indexname, tablename
FROM pg_indexes
WHERE schemaname = 'public';

Connection Limits

Configure your pool size based on your database's connection limit:

ProviderDefault Max Connections
AWS RDS (db.t3.micro)66
Cloud SQL (db-f1-micro)25
Supabase (Free)60
Neon (Free)100

Monitoring Queries

Check database health:

-- Active connections
SELECT count(*) as connections,
state,
application_name
FROM pg_stat_activity
GROUP BY state, application_name;

-- Database size
SELECT pg_size_pretty(pg_database_size(current_database()));

-- Table sizes
SELECT relname as table,
pg_size_pretty(pg_total_relation_size(relid)) as size
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

-- Slow queries (if pg_stat_statements enabled)
SELECT query,
calls,
round(mean_exec_time::numeric, 2) as avg_ms
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

Provider-Specific Guides

For detailed setup instructions, see the provider-specific guides:

Troubleshooting

Connection Refused

  1. Check firewall/security group rules allow your IP
  2. Verify the hostname and port
  3. Ensure SSL mode matches provider requirements

Authentication Failed

  1. Verify username and password
  2. Check if password needs URL encoding for special characters
  3. Ensure user has access to the specified database

SSL Certificate Error

  1. Use sslmode=require instead of verify-full
  2. Download and specify the provider's CA certificate
  3. Check certificate hasn't expired

Too Many Connections

  1. Use connection pooling
  2. Reduce application replica count
  3. Upgrade to a larger database instance