PostgreSQL Adapter
Overview
The PostgreSQL adapter connects to a PostgreSQL database server for durable, concurrent storage. It is the recommended adapter for production deployments.
Installation
The PostgreSQL adapter lives in a separate package:
npm i @bounda-dev/adapter-postgresql
Supported Features
| Feature | Supported |
|---|---|
| Event Store | Yes |
| Read Model | Yes |
| Policy DLQ | Yes |
| Process Manager DLQ | Yes |
| Scheduling | Yes |
When to Use
- Production deployments — Full durability, ACID transactions, and concurrent access.
- Multi-process applications — Safe concurrent writes from multiple server instances.
- Environments with existing PostgreSQL infrastructure — Reuse your existing database server.
Configuration
Every PostgreSQL configuration requires a url (connection string) and a schema (database schema name). Bounda creates the schema and tables automatically on first boot.
Event Store
domain: {
user: {
eventStore: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema: "bounda",
},
},
}
Read Model
read: {
"my-profile": {
type: "postgresql",
url: process.env.DATABASE_URL,
schema: "bounda",
},
}
Scheduling
domain: {
user: {
scheduling: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema: "bounda",
},
},
}
Process Manager DLQ
domain: {
user: {
processManagers: {
dlq: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema: "bounda",
},
},
},
}
Policy DLQ
domain: {
user: {
policies: {
dlq: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema: "bounda",
},
},
},
}
| Option | Type | Description |
|---|---|---|
type | "postgresql" | Adapter type |
url | string | PostgreSQL connection URL (e.g., postgresql://user:pass@host:5432/db) |
schema | string | Database schema name. Bounda creates it if it does not exist. |
Environment Variables
Using environment variables for connection details keeps secrets out of your codebase:
import type { Config } from "@bounda-dev/config";
const schema = process.env.BOUNDA_SCHEMA ?? "bounda";
export default {
domain: {
user: {
eventStore: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema,
},
scheduling: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema,
},
processManagers: {
dlq: {
type: "postgresql",
url: process.env.DATABASE_URL,
schema,
},
},
},
},
read: {
"my-profile": {
type: "postgresql",
url: process.env.DATABASE_URL,
schema,
},
},
} satisfies Config;
Testing
Integration tests for the PostgreSQL adapter use TestContainers to spin up a real postgres:17 instance. A single container is shared across all test suites via vitest’s globalSetup; each suite gets its own schema for isolation.
To run the tests locally, Docker must be running:
npm test --workspace=@bounda-dev/adapter-postgresql
Related
- Adapters Overview — Comparison of all available adapters
- SQLite — Lightweight alternative for development
- Configuration Reference — Full config reference