Skip to content

Postgres connection leak: StartClient creates a new sqlstore.Container per (re)connect and never closes it #165

Description

@luccas-silveira

StartClient builds a fresh sqlstore.Container at pkg/whatsmeow/service/whatsmeow.go:322 on every call. The container is a local variable and is never closed — there is no container.Close() anywhere in the file. Each call therefore leaks a whole database/sql pool.

This is not limited to the first connect: RestartInstance ends in Starting fresh instance -> StartInstance -> StartClient (whatsmeow.go:237), and WhatsApp drops the websocket on its own several times a day (Got 503 stream error, failed to read frame header: EOF), each drop triggering Disconnected detected, restarting instance.

Measured

v0.7.2, Postgres 15.6, a single connected instance, nobody using the panel: 17 backends on evogo_auth accumulated over 18h, with zero GET /instance/qr in the window.

  • Connections appear in pairs — the MaxIdleConns default of database/sql — and their backend_start timestamps match the restart lines in the log to the second.
  • 6 reconnects in 18h, so ~16 connections/day: max_connections=100 exhausted in ~6 days. We hit that twice.
  • Once exhausted, QR generation stops and sendText returns 500. The server then reconnects in a loop (11 Starting fresh instance in 80 seconds), burning whatever is left, so the saturation looks sudden.
  • It scales with instance count — ten numbers would saturate in half a day.

Requesting QR is just another path into the same StartClient, so /instance/qr makes it faster but is not the cause.

Suggested fix

Create the container once per process (the DSN never changes) and reuse it, or keep a reference per instance and Close() the old one before starting fresh.

Workaround

For anyone hitting this before a fix lands:

ALTER DATABASE evogo_auth SET idle_session_timeout = '1h';

Postgres then reaps the orphaned pools. Safe for live sessions: credentials live in the whatsmeow_* rows, not in the TCP connection, and pgx discards a dead connection silently before use. Took us from 17 backends to 6 with no disconnect and no re-pairing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions