FKITDEV — Server Session Too Low

Summary

The default Sequelize connection pool (max: 100) per process, across 7 Supervisor-managed processes, exhausts PostgreSQL connection slots in dev environments. Error: SequelizeConnectionError: remaining connection slots are reserved for roles with the SUPERUSER attribute — triggered in “Audit log forward” cron job.

Severity: P2 — Medium

Blocks dev workflows. Production may have higher max_connections but the underlying misconfiguration (no idle/acquire/evict) puts production at risk under load spikes.

Root Cause Analysis

  • server/db/sequelize.js only sets pool.max: 100, no lifecycle settings
  • 7 processes (main, cron, background, convert, media, storage, integration_log) x 100 = 700 potential connections
  • Default PostgreSQL max_connections is typically 100-200
  • No idle timeout — stale connections never released
  • No acquire timeout — requests hang indefinitely when pool exhausted
  • No eviction — dead connections accumulate
  • SIGUSR2 handler (force-release after 30s) suggests past connection leak issues

Affected Components

ComponentPath
Sequelize pool configserver/db/sequelize.js
Config layerconfig/dev.json, config/docker.json — no db.options overrides
All 7 Supervisor processesEach opens its own pool
Cron processFirst to fail — periodic jobs compete for last available slots
Pool monitorserver/db/sequelize.js — 5s interval, warns at 40%, errors at 60%

Bence László’s Review (Assignee)

Reviewer guidance

Jelenleg csak a pool maximum értéke van beállítva. Nem ezt kell feltétlenül növelni.

  1. Kapcsoljuk be az options.logging-ot és az options.benchmark-ot
  2. Megnézni, hogy a probléma nem abból fakad-e, hogy túl hosszú idle time van megadva, és/vagy az új kérések nem várnak eleget a connectionre (acquire)
  3. Készítsünk új konfigurációt

Reference: Sequelize v6 Constructor

Don't just bump max — add pool lifecycle management

pool: {
  max: 10,       // right-sized per process (7x10=70, safe for PG default)
  min: 2,
  idle: 10000,   // release connections idle >10s
  acquire: 30000, // timeout if no connection in 30s
  evict: 10000   // sweep stale connections every 10s
}

All overridable via db.options.pool.* in config files.

Debugging Checklist

  • Check PostgreSQL max_connections: SHOW max_connections;
  • Check active connections per process: SELECT usename, state, count(*) FROM pg_stat_activity GROUP BY 1,2;
  • Enable Sequelize logging + benchmark to identify slow queries holding connections
  • Check pool utilization via existing 5s monitor logs (40%/60% thresholds)
  • Check for connection leaks — SIGUSR2 handler firing = leaks present
  • Check if all 7 processes actually needed in dev
  • Measure idle vs active connections in pg_stat_activity
  • Test with reduced pool.max (e.g., 10) per process

Quick Fixes

  1. Add db.options.pool config in config/dev.json (right-size per process)
  2. Increase PostgreSQL max_connections (band-aid only)
  3. Disable unnecessary Supervisor processes in dev
  4. Add complete pool defaults in sequelize.js (long-term)

Escalation

If pool tuning doesn’t resolve: check for multiple Sequelize instances (grep 'new Sequelize'), consider PgBouncer for connection multiplexing.