Connection Pooling: Effiziente DB-Verbindungen | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

235 Dokumentationen verfügbar

Wissensdatenbank

Database Connection Pooling

Zuletzt aktualisiert: 20.01.2026 um 10:03 Uhr

Connection Pooling: Effiziente DB-Verbindungen

Connection Pools halten Datenbankverbindungen bereit. Das vermeidet den Overhead wiederholten Verbindungsaufbaus.

Das Problem

Ohne Pool:
Request 1 → Connect → Query → Disconnect  (~50ms overhead)
Request 2 → Connect → Query → Disconnect  (~50ms overhead)
Request 3 → Connect → Query → Disconnect  (~50ms overhead)

Mit Pool:
Pool: [Conn1, Conn2, Conn3, Conn4, Conn5]

Request 1 → Conn1 → Query → Return to Pool  (~1ms)
Request 2 → Conn2 → Query → Return to Pool  (~1ms)
Request 3 → Conn3 → Query → Return to Pool  (~1ms)

Node.js: pg Pool

const { Pool } = require('pg');

const pool = new Pool({
    host: process.env.DB_HOST,
    port: 5432,
    database: process.env.DB_NAME,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,

    // Pool-Konfiguration
    max: 20,                    // Max Verbindungen
    min: 5,                     // Min Verbindungen (warmhalten)
    idleTimeoutMillis: 30000,   // Idle Verbindung schließen nach 30s
    connectionTimeoutMillis: 5000,  // Timeout für neue Verbindung
});

// Event Listeners
pool.on('connect', () => console.log('New connection'));
pool.on('error', (err) => console.error('Pool error', err));

// Query (Pool managed automatisch)
async function getUsers() {
    const result = await pool.query('SELECT * FROM users LIMIT 10');
    return result.rows;
}

// Oder mit Client für Transaktionen
async function transferMoney(from, to, amount) {
    const client = await pool.connect();
    try {
        await client.query('BEGIN');
        await client.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, from]);
        await client.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, to]);
        await client.query('COMMIT');
    } catch (e) {
        await client.query('ROLLBACK');
        throw e;
    } finally {
        client.release();  // Zurück in Pool!
    }
}

// Cleanup bei Shutdown
process.on('SIGTERM', () => pool.end());

PHP: PDO Persistent Connections

<?php
// PDO mit persistenten Verbindungen
$pdo = new PDO(
    'mysql:host=localhost;dbname=mydb',
    'user',
    'password',
    [
        PDO::ATTR_PERSISTENT => true,  // Persistent Connection
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]
);

// Laravel: config/database.php
'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'options' => [
        PDO::ATTR_PERSISTENT => true,
    ],
],

Python: SQLAlchemy Pool

from sqlalchemy import create_engine
from sqlalchemy.pool import QueuePool

engine = create_engine(
    'postgresql://user:pass@localhost/db',
    poolclass=QueuePool,
    pool_size=5,           # Permanente Verbindungen
    max_overflow=10,       # Zusätzliche bei Bedarf
    pool_timeout=30,       # Warten auf freie Verbindung
    pool_recycle=1800,     # Verbindung alle 30min erneuern
    pool_pre_ping=True,    # Verbindung vor Nutzung testen
)

# Verwendung
with engine.connect() as conn:
    result = conn.execute(text("SELECT * FROM users"))
    for row in result:
        print(row)
# Connection automatisch zurück in Pool

Pool-Größe berechnen

# Faustregel:
connections = (core_count * 2) + effective_spindle_count

# Für SSD:
# effective_spindle_count ≈ 0

# Beispiel: 4 Cores
# connections = (4 * 2) + 0 = 8

# Beachten:
# - Zu wenig: Wartezeiten
# - Zu viel: DB-Overhead, Memory
# - Meist: 10-20 Verbindungen pro App-Instanz
# - DB-seitige Limits beachten!

PgBouncer (PostgreSQL Proxy)

# Zentraler Pool für mehrere App-Instanzen

[App 1] ──┐
[App 2] ──┼──> PgBouncer ──> PostgreSQL
[App 3] ──┘
          Pool           Single Connection Pool

# pgbouncer.ini
[databases]
mydb = host=localhost dbname=mydb

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt

pool_mode = transaction  # session, transaction, statement
max_client_conn = 1000
default_pool_size = 20

Monitoring

// Node.js: Pool-Statistiken
setInterval(() => {
    console.log({
        total: pool.totalCount,      // Alle Verbindungen
        idle: pool.idleCount,        // Verfügbar
        waiting: pool.waitingCount,  // Wartende Requests
    });
}, 10000);

// PostgreSQL: Aktive Verbindungen
SELECT count(*) FROM pg_stat_activity;

// MySQL: Verbindungen
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';

Best Practices

✅ Do:
  • Verbindungen immer zurückgeben (finally/using)
  • Pool-Events loggen (errors, timeouts)
  • Timeouts konfigurieren
  • Health Checks aktivieren
❌ Don't:
  • Verbindungen nicht releasen (Connection Leak!)
  • Pool zu groß konfigurieren
  • Globale Variable für einzelne Connection

Weitere Informationen

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120