chore(db): backend-aware pool sizes with env overrides

Per-backend defaults:
- Postgres: 25 max open / 25 max idle. Matching idle to open removes
  pool churn under bursts (Postgres handles concurrency at the server,
  idle connections are cheap).
- SQLite: 1 max open / 1 max idle. Single-writer model means a wider
  cap just queues behind busy_timeout; tight cap is honest.

Both back ends share ConnMaxLifetime=1h and ConnMaxIdleTime=30m so
stale connections (vault rotation, pgbouncer drops, load-balancer
idle eviction) rotate out without operator intervention.

Operators can override either default at boot via:
  XUI_DB_MAX_OPEN_CONNS=...
  XUI_DB_MAX_IDLE_CONNS=...

envInt parses these; missing/empty/non-positive values fall back to
the per-backend default.
This commit is contained in:
MHSanaei 2026-05-27 22:37:40 +02:00
parent d9ac8f0618
commit cfec48afec
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A

View file

@ -409,9 +409,19 @@ func InitDB(dbPath string) error {
if err != nil { if err != nil {
return err return err
} }
sqlDB.SetMaxOpenConns(8) var maxOpen, maxIdle int
sqlDB.SetMaxIdleConns(4) switch config.GetDBKind() {
case "postgres":
maxOpen = envInt("XUI_DB_MAX_OPEN_CONNS", 25)
maxIdle = envInt("XUI_DB_MAX_IDLE_CONNS", 25)
default:
maxOpen = envInt("XUI_DB_MAX_OPEN_CONNS", 8)
maxIdle = envInt("XUI_DB_MAX_IDLE_CONNS", 4)
}
sqlDB.SetMaxOpenConns(maxOpen)
sqlDB.SetMaxIdleConns(maxIdle)
sqlDB.SetConnMaxLifetime(time.Hour) sqlDB.SetConnMaxLifetime(time.Hour)
sqlDB.SetConnMaxIdleTime(30 * time.Minute)
if err := initModels(); err != nil { if err := initModels(); err != nil {
return err return err
@ -428,6 +438,18 @@ func InitDB(dbPath string) error {
return runSeeders(isUsersEmpty) return runSeeders(isUsersEmpty)
} }
func envInt(key string, def int) int {
v := strings.TrimSpace(os.Getenv(key))
if v == "" {
return def
}
n, err := strconv.Atoi(v)
if err != nil || n <= 0 {
return def
}
return n
}
// CloseDB closes the database connection if it exists. // CloseDB closes the database connection if it exists.
func CloseDB() error { func CloseDB() error {
if db != nil { if db != nil {