Connection Pooling

MoroJS database adapters include built-in connection pooling. Learn how to configure pool settings for optimal performance in your applications.

Basic Pool Configuration

Connection pooling reuses database connections to improve performance and reduce overhead. MoroJS provides intelligent pooling with sensible defaults.

Adapter Pool Configuration

typescript

1import { createApp, createDatabaseAdapter } from '@morojs/moro';
2
3const app = createApp();
4
5// PostgreSQL adapter with connection pooling
6const db = createDatabaseAdapter('postgresql', {
7  host: 'localhost',
8  port: 5432,
9  user: 'postgres',
10  password: process.env.DB_PASSWORD,
11  database: 'myapp',
12  
13  // Connection pool settings
14  connectionLimit: 20,        // Maximum connections in pool
15  acquireTimeout: 30000,      // Max time to wait for connection (ms)
16  timeout: 60000,             // Query timeout (ms)
17  ssl: false                  // SSL configuration
18});
19
20// MySQL adapter with different pool settings
21const mysqlDb = createDatabaseAdapter('mysql', {
22  host: 'localhost',
23  port: 3306,
24  user: 'root',
25  password: process.env.MYSQL_PASSWORD,
26  database: 'myapp',
27  
28  connectionLimit: 15,        // Smaller pool for MySQL
29  acquireTimeout: 20000,
30  timeout: 45000
31});
32
33// Pool automatically manages connections
34app.get('/users', async (req, res) => {
35  // Connection automatically acquired from pool
36  const users = await db.query('SELECT * FROM users');
37  // Connection automatically returned to pool
38  return { success: true, data: users };
39});

Pool Benefits

  • • Reduced connection overhead
  • • Better resource utilization
  • • Improved application performance
  • • Automatic connection lifecycle management
  • • Built-in error handling and recovery

Adapter Pool Settings

Environment-Specific Pool Configuration

typescript

1// Different pool settings for different environments
2const getPoolConfig = (env) => {
3  switch (env) {
4    case 'development':
5      return {
6        connectionLimit: 5,
7        acquireTimeout: 30000,
8        timeout: 30000
9      };
10      
11    case 'staging':
12      return {
13        connectionLimit: 10,
14        acquireTimeout: 45000,
15        timeout: 60000
16      };
17      
18    case 'production':
19      return {
20        connectionLimit: 25,
21        acquireTimeout: 60000,
22        timeout: 120000
23      };
24      
25    default:
26      return {
27        connectionLimit: 10,
28        acquireTimeout: 30000,
29        timeout: 60000
30      };
31  }
32};
33
34// Apply environment-specific configuration
35const poolConfig = getPoolConfig(process.env.NODE_ENV);
36
37const db = createDatabaseAdapter('postgresql', {
38  host: process.env.DB_HOST,
39  port: parseInt(process.env.DB_PORT || '5432'),
40  user: process.env.DB_USER,
41  password: process.env.DB_PASSWORD,
42  database: process.env.DB_NAME,
43  ...poolConfig
44});

Multiple Adapters with Different Pool Settings

typescript

1// Primary database - optimized for transactions
2const primaryDb = createDatabaseAdapter('postgresql', {
3  host: 'localhost',
4  user: 'postgres',
5  password: process.env.DB_PASSWORD,
6  database: 'myapp_primary',
7  connectionLimit: 20,
8  acquireTimeout: 30000,
9  timeout: 60000
10});
11
12// Analytics database - optimized for long queries
13const analyticsDb = createDatabaseAdapter('postgresql', {
14  host: 'analytics.example.com',
15  user: 'analytics',
16  password: process.env.ANALYTICS_PASSWORD,
17  database: 'analytics',
18  connectionLimit: 10,
19  acquireTimeout: 60000,    // Longer timeout for complex queries
20  timeout: 300000           // 5 minutes for analytics queries
21});
22
23// Cache database - lightweight SQLite
24const cacheDb = createDatabaseAdapter('sqlite', {
25  filename: 'cache.db',
26  memory: false
27});
28
29// Initialize all connections
30async function initializeDatabases() {
31  await Promise.all([
32    primaryDb.connect(),
33    analyticsDb.connect(),
34    cacheDb.connect()
35  ]);
36  console.log('All database adapters connected');
37}
38
39// Use appropriate database for each operation
40app.get('/users', async (req, res) => {
41  // Use primary database for user data
42  const users = await primaryDb.query('SELECT * FROM users LIMIT 20');
43  return { success: true, data: users };
44});
45
46app.get('/analytics/users', async (req, res) => {
47  // Use analytics database for complex reporting
48  const stats = await analyticsDb.query(`
49    SELECT 
50      DATE_TRUNC('day', created_at) as date,
51      COUNT(*) as user_count
52    FROM users 
53    WHERE created_at >= NOW() - INTERVAL '30 days'
54    GROUP BY DATE_TRUNC('day', created_at)
55    ORDER BY date
56  `);
57  return { success: true, data: stats };
58});

Connection Management

Connection Lifecycle

typescript

1// Basic connection management
2const db = createDatabaseAdapter('postgresql', {
3  host: 'localhost',
4  user: 'postgres',
5  password: process.env.DB_PASSWORD,
6  database: 'myapp',
7  connectionLimit: 20
8});
9
10// Connect to database
11await db.connect();
12console.log('Database connected');
13
14// Check connection status
15const isConnected = db.isConnected();
16console.log('Connection status:', isConnected);
17
18// Perform database operations
19const users = await db.query('SELECT * FROM users');
20
21// Graceful shutdown
22process.on('SIGINT', async () => {
23  console.log('Shutting down gracefully...');
24  await db.disconnect();
25  console.log('Database disconnected');
26  process.exit(0);
27});

Health Monitoring

typescript

1// Simple health check endpoint
2app.get('/health/database', async (req, res) => {
3  try {
4    // Test database connection
5    await db.query('SELECT 1');
6    
7    return {
8      status: 'healthy',
9      database: 'connected',
10      adapter: 'PostgreSQL',
11      timestamp: new Date().toISOString()
12    };
13  } catch (error) {
14    res.status(503);
15    return {
16      status: 'unhealthy',
17      database: 'disconnected',
18      error: error.message,
19      timestamp: new Date().toISOString()
20    };
21  }
22});
23
24// Connection info endpoint
25app.get('/admin/db-info', async (req, res) => {
26  return {
27    adapters: {
28      primary: {
29        type: 'PostgreSQL',
30        connected: primaryDb.isConnected(),
31        connectionLimit: 20
32      },
33      analytics: {
34        type: 'PostgreSQL',
35        connected: analyticsDb.isConnected(),
36        connectionLimit: 10
37      },
38      cache: {
39        type: 'SQLite',
40        connected: cacheDb.isConnected()
41      }
42    }
43  };
44});

Next Steps