Postgres backend (optional)
June 21, 2026 · View on GitHub
UniSchema defaults to SQLite for zero-config pilots. Set DATABASE_URL to a Postgres connection string to use Postgres instead.
When to use Postgres
- Multiple app instances need shared ingestion state
- HA failover with managed Postgres (RDS, Neon, Fly Postgres)
- Pilot outgrows single-instance SQLite (see benchmarks.md)
Quick start (Docker Compose)
docker compose -f docker-compose.postgres.yml up --build
Set in .env:
DATABASE_URL=postgres://unischema:unischema@postgres:5432/unischema
Manual setup
- Provision Postgres 14+
- Set
DATABASE_URL=postgres://user:pass@host:5432/dbname - Start the server — tables are created automatically on boot
npm run build
DATABASE_URL=postgres://... npm start
Fly.io Postgres
fly postgres create
fly postgres attach --app your-unischema-app
# Fly sets DATABASE_URL automatically
fly deploy --config deploy/fly.toml
Limitations (v0.2)
- Postgres and SQLite share the same Drizzle schema; migrations are
CREATE TABLE IF NOT EXISTSon startup - Rate limiting uses in-process counters by default; set
REDIS_URLfor shared rate limits across instances (see docker-compose.scale.yml) - Optional pg-boss ingest queue activates when
DATABASE_URLis Postgres andINGEST_QUEUE_ENABLEDis notfalse - Tests run against SQLite
:memory:by default
Switching from SQLite
- Export existing data if needed (constituent_events JSON from egress is the source of truth for analytics)
- Point
DATABASE_URLat Postgres - Re-register vendor webhooks if URLs changed during migration
Ingest history in SQLite is not automatically migrated — replay from vendor logs if required.