How to Set Up Server-Backed Persistence with PostgreSQL in OpenMAIC
Set up server-backed persistence with PostgreSQL in OpenMAIC by configuring a PostgreSQL 16 container, setting the DATABASE_URL environment variable, and allowing the storage runtime at packages/@openmaic/storage/src/runtime/pg.ts to automatically wire the PostgreSQL provider.
OpenMAIC stores runtime state—whiteboard edits, chat histories, and assets—in a pluggable persistence layer. While the system defaults to an in-memory KV store for client-side fallback, enabling durable, server-backed persistence with PostgreSQL in OpenMAIC ensures data survives server restarts and supports multi-instance deployments.
Understanding the OpenMAIC Persistence Architecture
The persistence stack consists of a generic interface and provider-specific implementations that are selected at runtime based on environment configuration.
The PersistenceProvider Interface
The contract for all storage operations is defined in packages/@openmaic/storage/src/runtime/types.ts. This interface specifies methods for CRUD operations on sessions, assets, and whiteboard state. The PostgreSQL implementation in packages/@openmaic/storage/src/runtime/pg.ts satisfies this interface by creating a node-postgres pool and translating all calls into SQL statements.
Auto-Detection Mechanism
When the OpenMAIC server starts, the storage layer checks for the presence of process.env.DATABASE_URL. If defined, the runtime automatically loads the PostgreSQL provider from packages/@openmaic/storage/src/runtime/pg.ts instead of the default in-memory store. This selection happens inside createPersistence(), the factory function exported by the storage package.
Configuring the PostgreSQL Container
The repository includes a PostgreSQL service definition in docker-compose.yml that runs PostgreSQL 16 with persistent volume storage.
# docker-compose.yml (excerpt)
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: openmaic
POSTGRES_PASSWORD: openmaic-dev
POSTGRES_DB: openmaic
volumes:
- openmaic-postgres:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
openmaic-postgres:
Start the database container:
docker compose up -d postgres
Setting Up the Environment Variables
The storage runtime requires a DATABASE_URL environment variable to establish the connection. The format follows the standard PostgreSQL connection URI scheme:
postgres://<user>:<password>@<host>:<port>/<database>
Create a local environment file:
cp .env.example .env.local
Add the connection string to .env.local:
# .env.local
DATABASE_URL=postgres://openmaic:openmaic-dev@localhost:5432/openmaic
The packages/@openmaic/storage/src/runtime/pg.ts file reads this variable at startup to instantiate the connection pool.
Initializing the Storage Runtime
No application code changes are required to switch storage backends. The entry point at packages/@openmaic/storage/src/lib/storage/client.ts exports createPersistence(), which automatically returns a PostgreSQL-backed instance when DATABASE_URL is present.
// Application code (no changes needed for PG switch)
import { createPersistence } from '@openmaic/storage';
const persistence = createPersistence();
// Automatically uses PostgreSQL if DATABASE_URL is set, otherwise falls back to memory
Verifying Persistence Functionality
Test the configuration by saving a whiteboard record and verifying it persists after a restart:
// Save a whiteboard record
await persistence.whiteboard.save({
sessionId: 'demo-session',
recordId: 'record-001',
data: { elements: [{ type: 'text', content: 'Hello' }] },
});
// After restarting the server, retrieve the record
const record = await persistence.whiteboard.load('demo-session', 'record-001');
console.log(record); // Contains the data saved before restart
Optional: Running the Reference Persistence Server
For multi-node deployments where multiple OpenMAIC instances must share the same storage backend, run the reference server located at packages/@openmaic/storage/src/server/index.ts. This exposes the persistence layer over HTTP/JSON-RPC, allowing remote runtime instances to access the same PostgreSQL database.
pnpm exec ts-node packages/@openmaic/storage/src/server/index.ts
This server reads the same DATABASE_URL environment variable and listens for incoming persistence requests from other OpenMAIC nodes.
Summary
- PostgreSQL Container: Define the service in
docker-compose.ymlusing the official PostgreSQL 16 image with a named volume for data durability. - Environment Configuration: Set
DATABASE_URLto a valid PostgreSQL connection string; the storage runtime inpackages/@openmaic/storage/src/runtime/pg.tsautomatically detects this and creates a connection pool. - Zero-Code Migration: Call
createPersistence()frompackages/@openmaic/storage/src/lib/storage/client.ts—the function automatically selects the PostgreSQL provider when the environment variable is present. - Reference Server: For distributed deployments, use
packages/@openmaic/storage/src/server/index.tsto expose persistence over HTTP.
Frequently Asked Questions
What is the correct format for the DATABASE_URL environment variable?
The URL must follow the PostgreSQL standard format: postgres://<user>:<password>@<host>:<port>/<db>. For example: postgres://openmaic:openmaic-dev@localhost:5432/openmaic. This is documented in packages/docs/content/docs/deployment.mdx and parsed by the runtime at packages/@openmaic/storage/src/runtime/pg.ts.
Where is the PostgreSQL persistence provider implemented in the OpenMAIC source code?
The provider is implemented in packages/@openmaic/storage/src/runtime/pg.ts. This file creates a node-postgres Pool instance from DATABASE_URL and implements the PersistenceProvider interface defined in packages/@openmaic/storage/src/runtime/types.ts.
Does OpenMAIC require code changes to switch from in-memory to PostgreSQL storage?
No. The storage client at packages/@openmaic/storage/src/lib/storage/client.ts exports createPersistence(), which auto-detects the presence of DATABASE_URL and automatically instantiates the PostgreSQL provider instead of the in-memory fallback.
How do I enable persistence across multiple OpenMAIC server instances?
Run the reference persistence server from packages/@openmaic/storage/src/server/index.ts. This process exposes the storage interface via JSON-RPC, allowing multiple OpenMAIC nodes to share the same PostgreSQL backend by communicating with the reference server rather than connecting to the database directly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →