Database Setup
Guide to choosing and configuring your PostgreSQL database provider - Neon, Supabase, or self-hosted
Content Rendering Error
This page contains invalid MDX syntax and cannot be fully rendered.
Language `env` is not included in this bundle. You may want to load it from external source.
Database Setup¶
The starter kit uses PostgreSQL with the pgvector extension for vector similarity search. This guide covers the recommended database providers.
Provider Comparison¶
| Feature | Neon | Supabase | Self-Hosted |
|---|---|---|---|
| Best For | Serverless, cost efficiency | Full backend platform | Complete control |
| Pricing | Pay-per-use, generous free tier | Free tier, then usage-based | Infrastructure cost only |
| pgvector | ✅ Built-in | ✅ Built-in | ✅ Manual install |
| Auto-scaling | ✅ Serverless | ❌ Fixed compute | ❌ Manual |
| Branching | ✅ Database branching | ❌ | ❌ |
| Backups | ✅ Automatic | ✅ Automatic | Manual |
| Pooling | ✅ Built-in | ✅ Built-in | PgBouncer |
Recommended: Neon¶
Neon is the recommended option for most deployments due to its serverless architecture and excellent developer experience.
Setup¶
- Create account at neon.tech
- Create a new project
- Enable pgvector extension:
sql CREATE EXTENSION vector; - Copy the connection string
Configuration¶
DATABASE_URL=postgres://user:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require
Features¶
- Serverless: Scales to zero when idle
- Branching: Create database branches for development/testing
- Point-in-time recovery: Restore to any point in time
- Connection pooling: Built-in connection pooler
Connection Pooling¶
Use the pooled connection string for Django:
# Pooled connection (recommended for Django)
DATABASE_URL=postgres://user:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require&pgbouncer=true
# Direct connection (for migrations)
DATABASE_URL_DIRECT=postgres://user:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require
Alternative: Supabase¶
Supabase is a good choice if you want additional features like authentication, storage, and edge functions.
Setup¶
- Create account at supabase.com
- Create a new project
- Enable pgvector in SQL editor:
sql CREATE EXTENSION vector; - Go to Settings → Database for connection string
Configuration¶
# Transaction pooler (recommended)
DATABASE_URL=postgres://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
# Direct connection
DATABASE_URL_DIRECT=postgres://postgres:[password]@db.[project-ref].supabase.co:5432/postgres
Supabase Features¶
- Built-in authentication (can replace or complement allauth)
- Storage for files and media
- Edge functions
- Real-time subscriptions
- REST and GraphQL APIs
Note on Authentication¶
When using Supabase, you can either:
1. Use django-allauth (recommended, current setup)
2. Use Supabase Auth with Django JWT validation
3. Hybrid approach for specific use cases
Self-Hosted: Docker Compose¶
For complete control or cost-sensitive deployments, self-host PostgreSQL.
Docker Compose Configuration¶
# compose.yaml
services:
db:
image: pgvector/pgvector:pg16
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: advantch
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD}
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
Configuration¶
DATABASE_URL=postgres://postgres:password@localhost:5432/advantch
Production Considerations¶
For production self-hosted deployments:
-
Connection Pooling: Add PgBouncer
yaml pgbouncer: image: edoburu/pgbouncer environment: DATABASE_URL: postgres://postgres:password@db:5432/advantch POOL_MODE: transaction MAX_CLIENT_CONN: 100 DEFAULT_POOL_SIZE: 20 -
Backups: Schedule regular backups
bash pg_dump -U postgres advantch > backup_$(date +%Y%m%d).sql -
Monitoring: Add pg_stat_statements
sql CREATE EXTENSION pg_stat_statements; -
High Availability: Consider Patroni or Stolon for clustering
Django Configuration¶
settings.py¶
import dj_database_url
DATABASES = {
"default": dj_database_url.config(
default="postgres://postgres:postgres@localhost:5432/advantch",
conn_max_age=600,
conn_health_checks=True,
)
}
pgvector Setup¶
Ensure pgvector is available:
# After running migrations
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS vector")
Migrations¶
Running Migrations¶
# Local
uv run python manage.py migrate
# Production (Fly.io)
fly ssh console -C "python manage.py migrate"
# Production (Docker)
docker compose exec django python manage.py migrate
Migration Best Practices¶
- Always backup before migrations
- Test migrations on a database branch (Neon) or staging
- Use
--planto preview migrations:
bash python manage.py migrate --plan
Vector Search Setup¶
For AI features using pgvector:
from pgvector.django import VectorField
class Document(models.Model):
content = models.TextField()
embedding = VectorField(dimensions=1536) # OpenAI embedding size
class Meta:
indexes = [
# IVFFlat index for faster similarity search
models.Index(
fields=['embedding'],
name='document_embedding_idx',
opclasses=['vector_cosine_ops']
)
]
Troubleshooting¶
Connection Issues¶
- Check connection string format
- Verify SSL mode for cloud providers
- Check firewall/security groups
- Use connection pooler for serverless
Performance Issues¶
- Enable
pg_stat_statementsfor query analysis - Check index usage with
EXPLAIN ANALYZE - Monitor connection count
- Consider read replicas for read-heavy workloads
Next Steps¶
Last updated on