Supabase Database
Supabase provides a managed PostgreSQL database with built-in connection pooling, auth, and storage. If you're also using Supabase for authentication or storage, this is a natural choice.
Getting Started
1. Create a Supabase Project
- Go to supabase.com and create an account
- Create a new project
- Wait for the database to be provisioned
2. Get Connection Details
In your Supabase dashboard:
- Go to Settings > Database
- Find the connection string under Connection string > URI
You'll see two options:
- Direct connection (port 5432) - For long-running processes
- Connection pooling (port 6543) - Recommended for serverless and high-concurrency
3. Configure Boards
Use the pooled connection URL for best performance:
# .env
BOARDS_DATABASE_URL=postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
Replace:
[project-ref]with your project reference (e.g.,abcdefghijkl)[password]with your database password[region]with your project's region (e.g.,us-east-1)
Connection Modes
Session Mode (Recommended)
For applications with persistent connections:
# Port 5432 - Direct connection
BOARDS_DATABASE_URL=postgresql://postgres.[ref]:[pass]@db.[ref].supabase.co:5432/postgres
Transaction Mode
For serverless deployments with many short-lived connections:
# Port 6543 - Pooled connection
BOARDS_DATABASE_URL=postgresql://postgres.[ref]:[pass]@aws-0-[region].pooler.supabase.com:6543/postgres
Transaction mode doesn't support prepared statements. Boards uses parameterized queries which work correctly in both modes.
Using with Supabase Auth
If you're using Supabase for both database and authentication:
# Database
BOARDS_DATABASE_URL=postgresql://postgres.[ref]:[pass]@aws-0-[region].pooler.supabase.com:6543/postgres
# Auth
BOARDS_AUTH_PROVIDER=supabase
SUPABASE_URL=https://[ref].supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
See Authentication for full auth setup.
Using with Supabase Storage
Supabase Storage can be used alongside the database:
# storage_config.yaml
default_provider: supabase
providers:
supabase:
type: supabase
bucket: boards-storage
# .env
SUPABASE_URL=https://[ref].supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
Free Tier Limits
Supabase's free tier includes:
| Resource | Limit |
|---|---|
| Database size | 500 MB |
| Bandwidth | 2 GB/month |
| Connections | 60 direct, unlimited pooled |
| Pausing | After 7 days inactive |
For production workloads, consider the Pro plan or higher.
Security
Database Password
Reset your database password in Settings > Database > Database password.
Service Role Key
The service role key bypasses Row Level Security. Keep it secure:
- Never expose in client-side code
- Store in environment variables or secrets manager
- Rotate periodically in Settings > API
IP Allowlist
Supabase allows connections from any IP by default. To restrict:
- Go to Settings > Database > Network Restrictions
- Add your server's IP addresses
Migrations
Boards manages its database schema using Alembic (not Supabase's built-in migration system). Migrations are located in packages/backend/alembic/versions/ and run against the boards schema.
To run migrations against your Supabase database:
# Set your Supabase connection string
export BOARDS_DATABASE_URL=postgresql://postgres.[ref]:[pass]@db.[ref].supabase.co:5432/postgres
# Run all migrations
cd packages/backend
uv run alembic upgrade head
Boards uses custom PostgreSQL trigger functions (e.g., boards.update_updated_at_column() for auto-updating updated_at timestamps) instead of Supabase's moddatetime extension. This keeps migrations portable across any PostgreSQL host, not just Supabase. These triggers coexist safely with Supabase's own schemas (auth, storage, etc.) since all Boards objects live in the boards schema.
Monitoring
Monitor your database in the Supabase dashboard:
- Database > Reports - Query performance
- Database > Postgres Logs - Connection and error logs
- Settings > Infrastructure - Resource usage
Troubleshooting
"Database is paused"
Free tier projects pause after 7 days of inactivity:
- Go to your project dashboard
- Click Restore project
- Consider upgrading to Pro for always-on
Connection Timeout
- Use the pooled connection URL (port 6543)
- Check your deployment region matches Supabase region
- Verify network connectivity to Supabase
"Prepared statement already exists"
Switch to transaction pooling mode or ensure your connection string uses port 6543.
Next Steps
- Supabase Auth Setup - Configure authentication
- Storage Configuration - Set up Supabase Storage