OpenMAIC Persistence Backends: Browser, HTTP, PostgreSQL, and S3 Explained
OpenMAIC provides four concrete persistence backends—Browser (IndexedDB), HTTP (REST API), PostgreSQL (SQL), and S3 (object storage)—that implement a unified RuntimeStore interface and can be selected via the NEXT_PUBLIC_PERSISTENCE environment variable.
OpenMAIC is a modular framework for building AI-driven applications that require reliable data persistence across diverse environments. The library abstracts all storage operations behind a small, runtime-store interface defined in packages/@openmaic/storage/src/runtime/types.ts, allowing developers to swap between local browser storage, remote HTTP APIs, production PostgreSQL databases, and Amazon S3 buckets without changing application logic.
The Runtime Store Interface
All persistence implementations conform to the RuntimeStore interface exported from packages/@openmaic/storage/src/runtime/types.ts. This contract defines standard methods for session management, append-only record storage, and document persistence. Every concrete backend performs envelope validation and stamps writes with the current DSL version before committing, ensuring data integrity regardless of the underlying storage mechanism.
Browser Backend: IndexedDB for Client-Side Storage
The Browser backend stores runtime sessions, append-only records, and document data directly in the user’s browser using IndexedDB.
Located in packages/@openmaic/storage/src/runtime/browser.ts, the BrowserRuntimeStore class creates two object stores—sessions and records—within a versioned IndexedDB database. This backend is the default when NEXT_PUBLIC_PERSISTENCE is unset, making it ideal for rapid prototyping and offline-first applications. All writes are atomic at the IndexedDB transaction level and include automatic schema validation against the current DSL version.
import { BrowserRuntimeStore } from '@openmaic/storage';
const store = new BrowserRuntimeStore();
// IndexedDB automatically initialized in the client
await store.saveSession({ id: 'session-123', data: {} });
HTTP Backend: REST API Persistence
The HTTP backend persists data to a remote OpenMAIC server through the public REST API endpoints under /api/persistence/*.
Implemented in packages/@openmaic/storage/src/runtime/http.ts, the HttpRuntimeStore encodes RuntimeSession and RuntimeRecord payloads as JSON and transmits them via the Fetch API. This backend validates the same envelopes as the browser store but delegates durable storage to the server. It is the preferred choice for SaaS deployments where client state must survive browser refreshes and be accessible across multiple devices.
import { HttpRuntimeStore } from '@openmaic/storage';
const store = new HttpRuntimeStore({
baseUrl: 'https://my-openmaic.example.com/api/persistence',
});
await store.appendRecord({ type: 'event', payload: {} });
PostgreSQL Backend: Durable Server-Side SQL
The PostgreSQL backend provides durable, server-side storage backed by the node-postgres library.
Found in packages/@openmaic/storage/src/runtime/pg.ts, the PgRuntimeStore initializes a pg.Pool connection and mirrors the browser store’s validation logic while using SQL transactions for atomicity. This backend stores sessions and records in PostgreSQL tables and supports concurrent access patterns required for production workloads. The implementation validates envelopes before executing parameterized INSERT statements, preventing SQL injection while maintaining type safety.
import { PgRuntimeStore } from '@openmaic/storage';
const store = new PgRuntimeStore({
connectionString: process.env.DATABASE_URL!, // postgres://user:pw@host/db
});
await store.saveSession({ id: 'prod-session-456', data: {} });
S3 Backend: Object Storage for Binary Assets
The S3 backend handles large binary assets such as audio, video, and PDF files outside the runtime store interface.
Located in packages/@openmaic/storage/src/asset/s3-bytes.ts, the S3AssetStore wraps the AWS SDK S3Client to perform PUT and GET operations against a configured bucket. Assets are referenced by deterministic keys and can be streamed directly from S3, reducing memory pressure on application servers. Unlike the runtime stores that handle structured session data, this backend is optimized for high-throughput byte storage and retrieval.
import { S3AssetStore } from '@openmaic/storage';
const store = new S3AssetStore({
bucket: 'my-openmaic-assets',
region: 'us-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
await store.put('audio/scene-42.wav', new Blob([audioBytes]));
const asset = await store.get('audio/scene-42.wav');
Configuration and Environment Selection
You can select a persistence backend by setting the NEXT_PUBLIC_PERSISTENCE environment variable or by importing the specific implementation programmatically. The runtime detects this variable during initialization and instantiates the corresponding store class. For Node.js server environments, PostgreSQL is typically selected for durability, while the Browser backend is automatically chosen for client-side bundles when no override is specified.
Summary
- Four concrete implementations ship with OpenMAIC:
BrowserRuntimeStore(IndexedDB),HttpRuntimeStore(REST),PgRuntimeStore(PostgreSQL), andS3AssetStore(object storage). - Unified interface (
RuntimeStoreinsrc/runtime/types.ts) ensures identical validation, DSL versioning, and transaction semantics across all backends. - Environment-driven selection via
NEXT_PUBLIC_PERSISTENCEallows deployment-time configuration without code changes. - Atomicity guarantees differ by backend: IndexedDB transactions for Browser, SQL transactions for PostgreSQL, and idempotent PUT operations for S3.
- Asset separation distinguishes runtime metadata (sessions/records) stored in Browser/HTTP/PostgreSQL from large binary objects stored in S3.
Frequently Asked Questions
How do I switch between persistence backends in OpenMAIC?
Set the NEXT_PUBLIC_PERSISTENCE environment variable to browser, http, or pg (PostgreSQL) before building your application. The storage module reads this variable at runtime and exports the corresponding store class. For S3 asset storage, import S3AssetStore directly from @openmaic/storage and instantiate it with your AWS credentials.
Can I use a different SQL database like MySQL instead of PostgreSQL?
The official PgRuntimeStore in packages/@openmaic/storage/src/runtime/pg.ts is the only full-SQL backend shipped with OpenMAIC. If you require MySQL or another RDBMS, you must implement the RuntimeStore interface defined in src/runtime/types.ts and provide your own connection pooling and query logic following the same envelope validation pattern used in the PostgreSQL adapter.
What is the difference between RuntimeStore and S3AssetStore?
RuntimeStore implementations (Browser, HTTP, PostgreSQL) handle structured, queryable data such as user sessions and append-only event records with strict schema validation. S3AssetStore operates outside this interface and manages opaque binary blobs (audio, video, PDFs) where only byte-level storage and retrieval are required, not complex querying or transactional updates.
Is the Browser backend suitable for production applications?
The Browser backend is suitable for production when data privacy requirements mandate client-side storage or for offline-capable progressive web applications. However, because IndexedDB data resides in the user’s browser, it is subject to storage quotas and can be cleared by browser privacy settings. For multi-device synchronization or critical data durability, deploy the HTTP or PostgreSQL backends instead.
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 →