Skip to main content

PostgreSQL Storage

PostgresStorage stores key-value data in PostgreSQL using a kv_store table with JSONB values. It requires the pg package and is ideal for production deployments, especially when running multiple server instances.

Installation

npm install pg

Setup

1

Install pg

Add the pg package to your project.
2

Create storage instance

Pass a PostgreSQL connection string to the constructor.
3

Call initialize()

Creates the kv_store table if it doesn’t exist. Required before any get/set operations.
import { PostgresStorage } from "@radaros/core";

const storage = new PostgresStorage(
  process.env.DATABASE_URL ?? "postgresql://user:pass@localhost:5432/mydb"
);

await storage.initialize(); // Required!

await storage.set("cache", "key1", { value: 42 });
const val = await storage.get("cache", "key1");

Constructor

connectionString
string
required
PostgreSQL connection string. Format: postgresql://user:password@host:port/database
const storage = new PostgresStorage(
  "postgresql://radaros:secret@localhost:5432/radaros_db"
);

Full Example

import { Agent, Memory, PostgresStorage, openai } from "@radaros/core";

const storage = new PostgresStorage(process.env.DATABASE_URL!);
await storage.initialize();

const memory = new Memory({
  storage,
  maxShortTermMessages: 50,
  enableLongTerm: true,
});

const agent = new Agent({
  name: "Assistant",
  model: openai("gpt-4o"),
  storage,
  memory,
});

const result = await agent.run("Hello!", { sessionId: "user-789" });

Schema

PostgresStorage creates a table kv_store:
ColumnTypeDescription
namespaceTEXTNamespace
keyTEXTKey within namespace
valueJSONBStored value (no manual JSON stringify)
updated_atTIMESTAMPTZLast update timestamp
Primary key: (namespace, key).

Multi-Instance Deployments

PostgresStorage is designed for horizontal scaling. Multiple Node.js processes can safely share the same PostgreSQL database.

Connection Pooling

The pg driver manages a connection pool internally. For high-concurrency deployments, configure the pool size:
import { PostgresStorage } from "@radaros/core";

const storage = new PostgresStorage(
  process.env.DATABASE_URL!,
  { max: 20 } // Max 20 connections in the pool (default: 10)
);
await storage.initialize();

Load Balancer Setup

┌─────────────┐     ┌──────────────┐
│  Instance 1  │────▶│              │
├─────────────┤     │  PostgreSQL  │
│  Instance 2  │────▶│              │
├─────────────┤     │   (shared)   │
│  Instance 3  │────▶│              │
└─────────────┘     └──────────────┘
All instances read and write to the same kv_store table. The (namespace, key) primary key ensures consistency, and JSONB values allow atomic updates.

Best Practices

  • Use a managed PostgreSQL service (RDS, Cloud SQL, Supabase) for production
  • Enable SSL for database connections: ?sslmode=require in the connection string
  • Monitor connection pool usage to avoid exhaustion under load
  • Run VACUUM ANALYZE kv_store periodically for optimal query performance

Environment Variables

DATABASE_URL=postgresql://user:password@host:5432/dbname

API Reference

MethodDescription
initialize()Creates kv_store table. Must be called before get/set.
get<T>(namespace, key)Get value. Returns null if not found.
set<T>(namespace, key, value)Store value. Uses JSONB for native JSON support.
delete(namespace, key)Remove key.
list<T>(namespace, prefix?)List keys. Prefix uses SQL LIKE.
close()Closes the connection pool.