Package Exports
- pg-multiverse
Readme
๐ PG Multiverse
Multi-cluster PostgreSQL manager for Node.js with TypeScript support
PG Multiverse is a powerful, enterprise-grade PostgreSQL multi-cluster manager that brings advanced database scaling capabilities to Node.js applications. With full TypeScript support, intelligent load balancing, distributed caching, and seamless multi-schema operations.
โจ Features
๐ข Multi-Cluster Management
- Read/Write Splitting - Automatic query routing to primary/replica clusters
- Intelligent Load Balancing - 5 strategies: round-robin, weighted, least-connections, response-time, health-aware
- Health Monitoring - Continuous health checks with automatic failover
- Multi-Schema Support - Route queries based on schema with zero configuration
โก Performance & Reliability
- Distributed Caching - Built-in Redis-like caching with TTL and invalidation
- Connection Pooling - Optimized connection management with warming and metrics
- Distributed Transactions - Cross-cluster ACID transactions with 2PC
- Automatic Failover - Zero-downtime cluster switching
๐ ๏ธ Developer Experience
- Full TypeScript Support - Type-safe queries with generics and interfaces
- Zero Configuration - Works out of the box with sensible defaults
- Rich Metrics - Detailed performance monitoring and health statistics
- Event-Driven - Comprehensive event system for monitoring and debugging
๐ Quick Start
Installation
npm install pg-multiverseBasic Usage
import { MultiClusterPostgres } from 'pg-multiverse';
// Define your data types
interface User {
id: number;
email: string;
name: string;
active: boolean;
}
// Initialize with cluster configuration
const postgres = new MultiClusterPostgres({
enableCache: true,
enableMetrics: true,
enableTransactions: true
});
await postgres.initialize({
users_cluster: {
schemas: ['users', 'auth'],
primary: {
host: 'primary.db.com',
port: 5432,
database: 'app_users',
user: 'postgres',
password: 'password'
},
replicas: [{
host: 'replica.db.com',
port: 5432,
database: 'app_users',
user: 'postgres',
password: 'password'
}]
}
});
// Type-safe queries with automatic cluster routing
const users = await postgres.query<User>(
'SELECT * FROM users WHERE active = $1',
[true],
{
schema: 'users', // Auto-routes to users_cluster
cache: true, // Cache results
cacheTtl: 300000 // 5 minute cache
}
);
// users.rows is automatically typed as User[]
users.rows.forEach(user => {
console.log(`${user.name} <${user.email}>`);
});Distributed Transactions
// Cross-cluster transactions
await postgres.withTransaction(['users', 'orders'], async (tx) => {
// Update user in users_cluster
await tx.query(
'UPDATE users SET last_order = NOW() WHERE id = $1',
[userId],
{ schema: 'users' }
);
// Create order in orders_cluster
const order = await tx.query<Order>(
'INSERT INTO orders (user_id, total) VALUES ($1, $2) RETURNING *',
[userId, total],
{ schema: 'orders' }
);
return order.rows[0];
});๐ Documentation
Core Concepts
Multi-Cluster Architecture
PG Multiverse manages multiple PostgreSQL clusters, each handling specific schemas:
const clusterConfig = {
// User data cluster
users_cluster: {
schemas: ['users', 'profiles', 'auth'],
primary: { /* primary connection */ },
replicas: [{ /* replica connections */ }],
readPreference: 'replica',
consistencyLevel: 'eventual'
},
// Commerce cluster
commerce_cluster: {
schemas: ['products', 'orders', 'payments'],
primary: { /* primary connection */ },
readPreference: 'primary',
consistencyLevel: 'strong'
}
};Load Balancing Strategies
- Round Robin (default) - Distributes requests evenly
- Weighted - Routes based on server weights
- Least Connections - Prefers servers with fewer active connections
- Response Time - Routes to fastest responding servers
- Health Aware - Combines multiple metrics for intelligent routing
{
loadBalancing: {
strategy: 'health_aware',
weights: {
'replica_1': 2,
'replica_2': 1
},
healthThreshold: 80
}
}Caching System
Built-in distributed caching with multiple invalidation strategies:
// Cache with automatic invalidation
await postgres.query('SELECT * FROM products', [], {
schema: 'products',
cache: true,
cacheTtl: 1800000, // 30 minutes
cacheKey: 'all_products',
tags: ['products', 'catalog'] // For bulk invalidation
});
// Invalidate cache
await postgres.invalidateCache({
schema: 'products'
});
await postgres.invalidateCache({
tags: ['products', 'inventory']
});API Reference
Core Methods
class MultiClusterPostgres {
// Initialize with cluster configuration
async initialize(config: ClusterConfiguration): Promise<void>
// Execute type-safe queries
async query<T>(sql: string, params?: any[], options?: QueryOptions): Promise<QueryResult<T>>
// Distributed transactions
async withTransaction<T>(schemas: string[], callback: TransactionCallback<T>): Promise<T>
// Health and metrics
async healthCheck(): Promise<HealthReport>
getMetrics(): SystemMetrics
// Cache management
async invalidateCache(criteria: InvalidationCriteria): Promise<number>
// Lifecycle
async close(): Promise<void>
}Configuration Options
interface MultiClusterConfig {
enableCache?: boolean; // Enable distributed caching
enableMetrics?: boolean; // Collect performance metrics
enableTransactions?: boolean; // Enable distributed transactions
cache?: {
maxSize?: number; // Max cache entries (1000)
ttl?: number; // Default TTL in ms (300000)
enableCompression?: boolean; // Compress large entries
};
cluster?: {
healthCheckInterval?: number; // Health check frequency (30000ms)
retryAttempts?: number; // Connection retry attempts (3)
maxFailuresBeforeMarkDown?: number; // Failures before marking down (3)
};
}๐๏ธ Advanced Usage
Sharding Support
{
orders_cluster: {
schemas: ['orders'],
sharding: {
strategy: 'hash',
key: 'user_id',
partitions: 4
},
primary: { /* config */ },
replicas: [
{ /* shard 1 replica */ },
{ /* shard 2 replica */ },
{ /* shard 3 replica */ },
{ /* shard 4 replica */ }
]
}
}Dynamic Schema Registration
// Register schemas at runtime
postgres.registerSchema('analytics', 'analytics_cluster', {
cacheStrategy: 'aggressive',
priority: 3
});
// Query the new schema
const events = await postgres.query(
'SELECT * FROM events WHERE date > $1',
[startDate],
{ schema: 'analytics' }
);Event Monitoring
// Monitor cluster health
postgres.on('clusterDown', ({ clusterId, reason }) => {
console.error(`Cluster ${clusterId} is down: ${reason}`);
// Trigger alerts, logging, etc.
});
postgres.on('clusterRecovered', ({ clusterId, downtime }) => {
console.log(`Cluster ${clusterId} recovered after ${downtime}ms`);
});
// Monitor cache performance
postgres.on('cacheHit', ({ key, schema }) => {
console.log(`Cache hit for ${key} in schema ${schema}`);
});
// Monitor query performance
postgres.on('queryExecuted', ({ duration, clusterId }) => {
if (duration > 1000) {
console.warn(`Slow query detected: ${duration}ms on ${clusterId}`);
}
});๐งช Testing
Unit Tests
npm testIntegration Tests
# With real PostgreSQL instances
npm run test:integrationCoverage Report
npm run test:coverage๐ Monitoring & Metrics
System Metrics
const metrics = postgres.getMetrics();
console.log(`Total Queries: ${metrics.totalQueries}`);
console.log(`Average Response Time: ${metrics.avgResponseTime}ms`);
console.log(`Error Rate: ${metrics.errorRate}%`);
// Per-cluster metrics
Object.entries(metrics.clusters).forEach(([clusterId, stats]) => {
console.log(`${clusterId}: ${stats.queries.total} queries, ${stats.connections.active} active connections`);
});
// Cache performance
if (metrics.cache) {
console.log(`Cache Hit Rate: ${(metrics.cache.hitRate * 100).toFixed(2)}%`);
console.log(`Cache Size: ${metrics.cache.itemCount} items`);
}Health Monitoring
const health = await postgres.healthCheck();
Object.entries(health).forEach(([clusterId, status]) => {
console.log(`${clusterId}: ${status.healthy ? 'โ
' : 'โ'} (${status.responseTime}ms)`);
if (!status.healthy) {
console.error(`Error: ${status.error}`);
console.log(`Failure Count: ${status.failureCount}`);
}
});๐ Performance
Benchmarks
| Feature | Performance |
|---|---|
| Connection Pooling | 10,000+ concurrent connections |
| Query Caching | 95%+ cache hit rates |
| Load Balancing | Sub-1ms routing overhead |
| Health Checks | 30s intervals, <5ms latency |
| Failover Time | <2s automatic recovery |
Production Tips
Connection Tuning
{ connectionPool: { min: 5, // Always keep 5 connections warm max: 50, // Scale up to 50 under load warmupConnections: true } }
Cache Optimization
{ cache: { maxSize: 10000, // Increase for high-traffic apps enableCompression: true, // Save memory on large results compressionThreshold: 1024 } }
Health Check Tuning
{ cluster: { healthCheckInterval: 15000, // More frequent checks maxFailuresBeforeMarkDown: 5 // More resilient to transient issues } }
๐ Use Cases
๐ E-commerce Applications
- User Cluster: customers, profiles, authentication
- Catalog Cluster: products, categories, inventory
- Order Cluster: orders, payments, shipping
- Analytics Cluster: events, metrics, reports
๐ข Multi-tenant SaaS
- Tenant Isolation: Separate clusters per tier
- Shared Services: Common clusters for billing, analytics
- Geographic Distribution: Region-specific clusters
๐ง Microservices Architecture
- Service Isolation: One cluster per microservice
- Cross-service Transactions: Distributed transactions
- Centralized Monitoring: Unified metrics and health
๐ Data-intensive Applications
- OLTP/OLAP Separation: Transactional vs analytical workloads
- Read Scaling: Multiple read replicas
- Cache Optimization: Aggressive caching for hot data
๐ฆ Migration Guide
From pg to pg-multiverse
// Before: Direct pg usage
import { Pool } from 'pg';
const pool = new Pool({ /* config */ });
const result = await pool.query('SELECT * FROM users');
// After: PG Multiverse with type safety
import { MultiClusterPostgres } from 'pg-multiverse';
const postgres = new MultiClusterPostgres();
await postgres.initialize(config);
const result = await postgres.query<User>('SELECT * FROM users');From Single Database
- Start with single cluster
- Add read replicas
- Introduce schema-based routing
- Scale to multiple clusters
๐ค Contributing
We welcome contributions! Please see our Contributing Guide.
Development Setup
# Clone the repository
git clone https://github.com/andeerc/pg-multiverse.git
cd pg-multiverse
# Install dependencies
npm install
# Run tests
npm test
# Build the project
npm run build๐ Changelog
See CHANGELOG.md for version history.
๐ License
MIT ยฉ PG Multiverse Team
๐ Acknowledgments
- PostgreSQL Community - For the amazing database
- Node.js pg Driver - Reliable PostgreSQL connectivity
- TypeScript Team - Type safety and developer experience
- Contributors - Everyone who helped make this project better
๐ Star us on GitHub โข ๐ Documentation โข ๐ฌ Discord Community โข ๐ Report Bug
Made with โค๏ธ by the PG Multiverse Team