Erro "FATAL: remaining connection slots are reserved" no PostgreSQL durante pico de faturamento

Por · Publicado em · 8 min de leitura

Tela de monitor com interface técnica em tons verdes mostrando gráficos e indicadores desfocados
Ilustra monitoramento de métricas e picos de sistema durante sobrecarga Foto: Tima Miroshnichenko / Pexels

O erro "FATAL: remaining connection slots are reserved" no PostgreSQL durante pico de faturamento indica que quase todos os slots de conexão acabaram e os restantes estão reservados para o superusuário. O efeito é bloqueio de logins da aplicação. Veja como diagnosticar em minutos, liberar conexões com segurança e aplicar correções rápidas que estabilizam o ambiente.

O que esse erro significa e por que aparece

O PostgreSQL reserva alguns slots de conexão para o superusuário. Quando os demais se esgotam, usuários comuns recebem o erro. Isso ocorre em picos, tempestades de conexões e sessões presas em "idle in transaction".

Não é só falta de max_connections. Ausência de pooler, reinícios simultâneos de workers web e jobs paralelos agravam. Se o problema for genérico de lotação, veja também o guia de "Too many connections". Para carga contínua pesada, veja o serviço de hardening e tuning de PostgreSQL.

  • Conexões normais esgotadas; sobram apenas slots reservados ao superusuário.
  • Aplicações sem pool ampliam picos ao abrir muitas conexões curtas.
  • Sessões "idle in transaction" mantêm slots ocupados por muito tempo.

O que conferir primeiro durante o pico?

Você precisa de visibilidade imediata: quantos slots existem, quem está ocupando e em que estado. Priorize acesso administrativo e reduza a dependência de rede conectando via socket local, se disponível.

Use consultas rápidas para limites, agrupamento por estado/usuário/aplicação e top sessões ativas ou presas. Esses dados guiam as primeiras ações com menor risco.

-- Limites atuais
SELECT name, setting FROM pg_settings
WHERE name IN ('max_connections','superuser_reserved_connections');

-- Quem está ocupando mais conexões agora?
SELECT state, application_name, usename, client_addr, count(*) AS qtd
FROM pg_stat_activity
GROUP BY 1,2,3,4
ORDER BY qtd DESC;

-- Top sessões ativas ou presas em transação
SELECT pid, state, xact_start, wait_event_type, wait_event, application_name, query
FROM pg_stat_activity
WHERE state IN ('active','idle in transaction')
ORDER BY xact_start NULLS LAST
LIMIT 20;

Como liberar conexões com segurança sem reiniciar?

Cancele consultas longas antes de encerrar sessões. Encerrar força rollback da transação; escolha alvos de baixo risco e comunique o time de negócio.

Reduza a taxa de novas conexões na aplicação: ative ou ajuste o pool do driver, limite processos web temporariamente e suspenda tarefas de fundo não críticas até estabilizar.

  • Cancelar consultas antes de finalizar sessões reduz impacto.
  • Atue primeiro em sessões "idle in transaction" muito antigas.
  • Diminua novas conexões na camada de aplicação durante a normalização.
-- 1) Cancelar consultas em execução (encerra com graça)
SELECT pg_cancel_backend(pid)
FROM pg_stat_activity
WHERE state = 'active' AND now() - xact_start > interval '30 seconds';

-- 2) Encerrar sessões problemáticas (gera rollback)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction' AND now() - xact_start > interval '2 minutes';

Quais ajustes rápidos no PostgreSQL ajudam no pico?

Alguns parâmetros aliviam a saturação, mas mudanças em max_connections e superuser_reserved_connections exigem reinício. Planeje memória e testes antes de alterar.

O caminho sustentável é manter um limite razoável de conexões no PostgreSQL e colocar um pooler à frente. Isso reduz churn e estabiliza a latência sob pico.

Componente Parâmetro/Opção O que faz Risco/Observação
PostgreSQL max_connections Aumenta o número de conexões simultâneas aceitas. Requer restart; mais conexões elevam uso de memória e context-switch.
PostgreSQL superuser_reserved_connections Reserva slots para superusuário acessar quando o banco satura. Requer restart; não zere. Mantenha poucos, porém suficientes.
PgBouncer pool_mode = transaction Reutiliza conexões por transação, reduzindo saturação. Quebra recursos de sessão (tabelas temporárias, prepared statements de sessão, LISTEN/NOTIFY).
PgBouncer reserve_pool_size Mantém conexões de servidor sobressalentes para picos. Ajuste junto com max_client_conn e default_pool_size.
SO (Linux) net.core.somaxconn Aumenta a fila de aceitação de conexões (accept queue). Ajuda sob tempestade; não resolve estouro de max_connections.
SO (Linux) net.ipv4.tcp_max_syn_backlog Aumenta fila de SYN pendentes no handshake. Reduz perdas em rajadas; não substitui pooler.
Aplicação Pool no driver/ORM Reúso de conexões e limitação de concorrência. Evite abrir/fechar por requisição; prefira conexões persistentes.
# Exemplos no postgresql.conf (requer restart)
max_connections = 300
superuser_reserved_connections = 3

Pool de conexões: quando usar PgBouncer e quais modos

Use PgBouncer quando a aplicação abre muitas conexões curtas ou vários processos sobem em paralelo. O modo transaction pooling atende a maioria dos cenários web por reduzir sessões no servidor.

Evite transaction pooling se precisa de estado de sessão, como tabelas temporárias, prepared statements por sessão ou LISTEN/NOTIFY. Nesse caso, use session pooling ou adapte a aplicação.

  • Transaction pooling: ideal para HTTP com consultas curtas e alta taxa de requisições.
  • Session pooling: preserva sessão, porém escala menos.
  • Ajuste max_client_conn, default_pool_size e reserve_pool_size conforme a carga.
# Exemplo mínimo de PgBouncer
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
listen_port = 6432
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50
min_pool_size = 5
reserve_pool_size = 20
server_reset_query = DISCARD ALL

Backlog e kernel para segurar tempestades de conexões

Rajadas de novas conexões podem enfileirar o accept do sistema. Ajustar somaxconn e tcp_max_syn_backlog reduz recusas sob pico, sem criar mais slots no PostgreSQL.

A correção estrutural continua sendo limitar concorrência com pooler e reuso no app. O backlog é complementar e deve ser validado em staging. Mudanças de sysctl afetam todo o sistema.

  • Persistir ajustes em /etc/sysctl.d/ e versionar o arquivo.
  • Testar em ambiente de staging antes de produção.
  • Monitorar novas conexões por segundo e falhas de handshake.
# Ajustes temporários (teste controlado)
sudo sysctl -w net.core.somaxconn=4096
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=8192

# Persistir em /etc/sysctl.d/99-tuning.conf
# net.core.somaxconn=4096
# net.ipv4.tcp_max_syn_backlog=8192
# sudo sysctl --system

Como evitar que volte a acontecer?

Defina limites claros e crie visibilidade contínua. Métricas e alertas sobre conexões, estados de sessão e tempo de transação evitam repetição durante faturamento.

Monte um runbook com consultas de diagnóstico e critérios para cancelar ou encerrar sessões. Treine a equipe e valide o plano. Para disciplina transacional, veja o guia de migrations e rollbacks em PostgreSQL e implemente alertas com base em runbooks, como no serviço de observabilidade e runbooks.

  • Colete métricas: conexões ativas, novas conexões por segundo e "idle in transaction".
  • Alerta quando "idle in transaction" ultrapassar um limiar definido.
  • Simule pico com carga sintética para validar configurações.

Perguntas frequentes

Aumentar max_connections resolve o erro definitivamente?

Não. Aumentar max_connections alivia no curto prazo, mas pode piorar latência e consumo de memória. O caminho sustentável é usar pool de conexões (PgBouncer ou no driver) e corrigir sessões longas, combinando com ajuste moderado do limite.

Posso mudar superuser_reserved_connections sem reiniciar o PostgreSQL?

Não. superuser_reserved_connections, assim como max_connections, requer reinício do servidor. Planeje janela e valide memória antes. Para alívio imediato, cancele/encerre sessões e reduza novas conexões via pooler e aplicação.

Como identificar rapidamente quem mais consome conexões no momento?

Agrupe pg_stat_activity por state, application_name, usename e client_addr. As contagens por grupo evidenciam quais serviços, usuários ou hosts saturam. Filtre por "idle in transaction" e duração da transação para priorizar a ação com menor risco.

PgBouncer em transaction pooling quebra quais recursos?

Transaction pooling não preserva estado de sessão entre comandos. Recursos como tabelas temporárias, prepared statements por sessão, SET LOCAL e LISTEN/NOTIFY podem falhar. Se precisar deles, use session pooling ou adapte a aplicação para transações curtas e sem estado.

É melhor matar sessões ou apenas cancelar consultas longas?

Comece com pg_cancel_backend, que tenta encerrar a consulta sem derrubar a sessão. Se não resolver, use pg_terminate_backend em sessões de baixo risco, ciente do rollback. Priorize sessões "idle in transaction" antigas e queries claramente travadas.

Backlog do kernel aumenta a capacidade de conexões do PostgreSQL?

Não. Backlog (somaxconn, tcp_max_syn_backlog) apenas melhora a fila de aceitação do sistema sob rajadas de novas conexões. A capacidade de sessões simultâneas depende de max_connections e da eficiência do pool de conexões.

Precisa destravar o banco sem arriscar dados?

Se o erro surgiu no pico de faturamento, um diagnóstico rápido e ajustes de pool, limites e backlog podem estabilizar o ambiente. Vamos conversar sobre um plano seguro.

Falar sobre diagnóstico rápido

Veja também