Skip to content

Postgres

A single infra-postgres container hosts most databases. Each application connects with its own role and is constrained to its own DB.

Databases

Database Size
down_rabbit_hole 25 GB
litellm 2914 MB
jb2b 1267 MB
gamine_brain 382 MB
ghrepos 220 MB
vikunja 12 MB
expense_report 8263 kB
darah 8231 kB
dashboard 7679 kB

Gamine has its own Postgres container (gamine-db) because of its volume of writes and its independent backup/restore lifecycle. Odoo has its own (sandbox-odoo-db) for the same reason.

Extensions

  • pgvector — enabled on jb_brain, jb2b, geopolitics, obsidian_brain for embedding search
  • pgcrypto — enabled where field-level encryption is needed (MedVault will use this when deployed)
  • pg_stat_statements — enabled on all DBs for query profiling

Embedding dimensions

All vector columns use 768 dims (Gemini embedding via LiteLLM, free tier). Older 3072-dim columns are being migrated — tracked at Vikunja #491.

Access patterns

  • Apps connect via Docker network using infra-postgres:5432
  • No public exposure
  • Read replicas: none (not justified at this scale)
  • Connection pooling: each app uses its own asyncpg pool, sized to its worker count

Migrations

  • Alembic per project, never raw SQL in code
  • Every migration must have up() AND down() — irreversible migrations are rejected at review
  • Migrations run on container start in dev; explicitly invoked in prod

Backups

See backups.md. pg_dump per DB, retained 30 days.