PRODPlataforma BaaS europeia soberanaAbra o painel →

Desempenho · 11 minutos de leitura

Postgres ajuste de produção que reduz a latência

Affane Daylami · Fondateur · 3 de junho de 2026

Voltar ao blog

Uma lista de verificação de ajuste do Postgres em produção é dividida em cinco seções: conexões e pooling, memória, autovacuum, consultas e índices lentos, depois pontos de verificação e WAL. O resto é apenas uma variação desses cinco pontos dependendo da sua carga. Os parâmetros que aparecem com mais frequência, shared_buffers, work_mem e Effective_cache_size, são detalhados abaixo com seus pontos de partida.

Este texto em inglês foi gerado automaticamente a partir do original em francês e ainda não foi revisado.
Esta página foi traduzida automaticamente. A versão em inglês é oficial.

postgresql.conf por padrão não está quebrado, é prudente: dimensionado para rodar em uma máquina mínima sem nunca causar falha na instalação, não para lidar com o tráfego de produção. A passagem desses valores de compatibilidade aos valores de produção é medida, não pode ser adivinhada. Para o protocolo de medição em si (carga realista, p50/p95/p99, resultados reproduzíveis), consulte nossa metodologia de benchmark de back-end . Este artigo detalha as configurações em si, na ordem em que são mais importantes.

O essencial
  • Cinco projetos, em ordem: conexões/pooling, memória, autovacuum, índices/consultas lentas, pontos de verificação/WAL.
  • max_connections e shared_buffers requerem uma reinicialização completa do servidor; a maioria das outras configurações são carregadas a quente.
  • Nunca desative o autovacuum na produção: o risco real não é a lentidão, é o encapsulamento do ID da transação.
  • pg_stat_statements deve ser listado em shared_preload_libraries antes que um simples CREATE EXTENSION colete qualquer coisa.
  • O Advisor integrado ao Aurabase Studio já aplica parte deste checklist automaticamente: solicitações com duração superior a 150 ms, chaves estrangeiras não indexadas, pool de conexões acima de 80% de saturação.
#
Ponto de partida

Por que os padrões do Postgres nunca são suficientes

postgresql.conf, em seu estado padrão, foi projetado para nunca falhar em uma instalação e não absorver seu tráfego. O valor histórico de shared_buffers, 128 MB, permite que o Postgres seja iniciado em uma máquina mínima sem reservar recursos críticos. max_connections em 100 cabe em um pequeno servidor compartilhado. Nenhum dos dois foi escolhido para sua carga real.

Portanto, o problema não é que o Postgres esteja mal configurado por padrão: é que ele nunca foi configurado para você. As seções a seguir abordam as configurações na ordem em que mais compensam, desde o gargalo mais comum (as conexões) até o que aparece mais lentamente (o WAL).

#
Conexões

Dimensione max_connections e pooling antes de tudo

O primeiro projeto não é memória, são conexões. Cada conexão Postgres abre um processo de servidor dedicado que consome RAM e tempo de CPU de contexto, mesmo se estiver ocioso. Aumentar max_connections para evitar erros do tipo "muitas conexões" muda o problema: além de um certo número de conexões ativas simultâneas, a contenção de CPU degrada a latência de todas as solicitações, inclusive as mais rápidas.

A abordagem correta inverte a ordem usual: dimensione max_connections na simultaneidade real do servidor e, em seguida, absorva a simultaneidade do lado do aplicativo com um pooler como PgBouncer em pool_mode=transaction. O pooler multiplexa centenas de conexões de clientes em um punhado de conexões de servidores realmente ativas. Nosso artigo dedicado detalha o mecanismo do modo de transação e seus limites (declarações preparadas, LISTEN/NOTIFY) e uma comparação entre PgBouncer, Supavisor e PgCat para escolher a implementação.

max_connections é um parâmetro de contexto "postmaster": alterá-lo requer uma reinicialização completa do servidor, não uma simples recarga. Em instâncias Postgres dedicadas do Aurabase (planos Pro e Enterprise, um cluster CNPG por projeto), essa configuração é configurada por nível de plano em vez de deixada com seu valor padrão. Um reinício não é uma operação trivial de repetir na produção, o que justifica esta escolha por etapas e não por um valor fixo. A fórmula para escolher seu próprio valor, com seus limites, é assunto de um artigo separado: size max_connections.

#
Memória

shared_buffers, work_mem, Effective_cache_size: as configurações que importam

Quatro configurações de memória pesam mais do que todas as outras combinadas: shared_buffers, effective_cache_size, work_mem e maintenance_work_mem. Os três primeiros determinam quantos dados o Postgres mantém na memória antes de retornar ao disco; o quarto determina a velocidade de criação de um VACUUM ou índice.

shared_buffers define o cache interno compartilhado por todas as conexões. O benchmark comumente documentado pelo projeto PostgreSQL é de aproximadamente 25% da RAM disponível em um servidor de banco de dados dedicado. Além disso, os ganhos diminuem e o cache de disco do sistema operacional assume o controle. effective_cache_size não aloca nada: é uma estimativa, dada ao planejador de consultas, da memória total disponível para o cache (Postgres e SO combinados). O subdimensionamento empurra o agendador para varreduras sequenciais, enquanto um índice armazenaria em grande parte o cache; o benchmark atual está entre 50 e 75% de RAM.

work_mem é a armadilha mais comum. Este não é um limite global. Cada operação de classificação ou hash em uma consulta pode consumir sua própria parte dela, e uma consulta com múltiplas junções pode reservar sua própria parte várias vezes. Um valor muito generoso combinado com um max_connections alto pode esgotar a RAM do servidor sob carga simultânea, mesmo que cada solicitação considerada isoladamente pareça razoável. maintenance_work_mem, por outro lado, pode permanecer significativamente mais generoso: aplica-se apenas a operações de manutenção (VACUUM, CREATE INDEX), que raramente são simultâneas entre si.

Apenas shared_buffers requer uma reinicialização. Os outros três são recarregados a quente, inclusive para uma sessão isolada: SET work_mem = '64MB'; durante uma única solicitação gananciosa, sem afetar a configuração global.

#
Manutenção

Autovacuum: ajuste os limites, nunca desative-o

Nunca desative o autovacuum na produção, mesmo que temporariamente, para “liberar recursos” durante um pico de carga. Postgres usa MVCC: cada UPDATE e cada DELETE deixa um prazo que somente o vácuo pode recuperar. Sem ele, as tabelas incham, os índices degradam-se e os planos de execução deterioram-se gradualmente, sem erros visíveis até ser tarde.

O verdadeiro risco não é a lentidão

O perigo mais sério de um autovacuum desativado ou subdimensionado não é o desempenho, mas o encapsulamento do ID da transação. Após um limite, o Postgres muda todo o banco de dados para somente leitura para evitar corrupção de dados, até que um VACUUM manual seja executado. Este é um incidente de produção totalmente evitável através da configuração correta.

O valor padrão deautovacuum_vacuum_scale_factor (20% de linhas mortas antes do acionamento) é adequado para uma tabela pequena, não para uma tabela com vários milhões de linhas com uso intensivo de gravação. Em uma tabela de 10 milhões de linhas, esses 20% representam 2 milhões de linhas mortas acumuladas antes da primeira passagem. Reduza esse limite tabela por tabela em vez de alterar o valor geral de todo o banco de dados.

psqlsql
-- Reduza o limite em uma tabela com muitas gravações, não em geral
ALTER TABLE orders SET (
  autovacuum_vacuum_scale_factor = 0.05,
  autovacuum_vacuum_cost_limit = 2000
);

O Advisor integrado ao Aurabase Studio verifica esta configuração a cada análise do projeto, da mesma forma que as tabelas sem chaves primárias ou chaves estrangeiras não indexadas. Este é um sinal explícito e não uma degradação silenciosa descoberta tarde demais.

#
Consultas lentas

Indexar antes de adicionar RAM

A maioria dos problemas de latência na produção não vem nem da CPU nem da RAM: eles vêm de um índice ausente ou mal escolhido. Antes de tocar em um único parâmetro de postgresql.conf, EXPLAIN (ANALYZE, BUFFERS) na consulta em questão continua sendo o diagnóstico mais confiável. Reduz a latência da solicitação do Postgres bem antes de adicionar recursos.

psqlsql
-- Diagnosticar uma consulta lenta antes de tocar na configuração
EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, o.total
FROM orders o
WHERE o.customer_id = '…'
ORDER BY o.created_at DESC
LIMIT 20;

Um Seq Scan em uma tabela com vários milhões de linhas, onde um Index Scan era esperado, quase sempre sinaliza um problema de índice. Três causas surgem com mais frequência: um índice ausente, um tipo de coluna incompatível com o índice existente ou estatísticas obsoletas após uma importação massiva sem ANALYZE. Adicionar RAM ou aumentar work_mem às vezes oculta esse sintoma em um pequeno volume de dados; o problema reaparece assim que a mesa cresce.

Para localizar essas solicitações sem pesquisá-las uma por uma, pg_stat_statements agrega as estatísticas de execução de todas as solicitações do servidor. Uma armadilha comum: a extensão deve primeiro ser listada em shared_preload_libraries, um parâmetro de contexto "postmaster" que requer uma reinicialização. Sem esta etapa, CREATE EXTENSION pg_stat_statements; é bem-sucedido silenciosamente, mas não coleta nada.

postgresql.conf → psqlsql
# Requer uma reinicialização completa (parâmetro "postmaster")
shared_preload_libraries = 'pg_stat_statements'

-- Depois que o servidor for reiniciado, em cada banco de dados a ser auditado:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT query, calls, mean_exec_time, max_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

Este é exatamente o erro que o backend do Aurabase retorna quando esta extensão está ausente: uma mensagem explícita em vez de uma lista vazia silenciosa, que pode ser confundida com "nenhuma consulta lenta". O Studio Advisor vai além: classifica automaticamente qualquer solicitação com tempo médio superior a 150 ms como aviso e acima de 500 ms como crítica. Esses limites são baseados nas mesmas estatísticas pg_stat_statements.

#
Gravação de disco

Checkpoints e WAL: suavizam a carga em vez de sofrê-la

Um ponto de verificação força o Postgres a gravar no disco todas as páginas modificadas na memória desde a anterior. Por padrão, este texto pode se concentrar em uma janela de tempo muito curta. O resultado é um aumento notável na latência do disco no lado do aplicativo, o tipo de lentidão periódica que é difícil de relacionar a uma solicitação específica.

checkpoint_completion_target controla a propagação desta escrita no intervalo entre dois pontos de verificação. Um detalhe que faltava nas checklists mais antigas: o PostgreSQL 14, lançado em 2021, mudou seu valor padrão de 0,5 para 0,9. Em uma instância do PostgreSQL 16, como clusters de locatários dedicados do Aurabase, essa configuração já está correta por padrão; ajustá-lo manualmente só faz sentido em uma versão anterior à 14. Veja nossa comparação PostgreSQL 16 vs 17 vs 18 para outras alterações de versão que afetam o ajuste.

max_wal_size atua na mesma direção: um valor muito baixo aciona pontos de verificação mais frequentes do que o esperado, mesmo quando checkpoint_timeout ainda não foi alcançado. Aumentá-lo reduz a frequência dos pontos de verificação, ao custo de um tempo de recuperação mais longo após uma falha, uma vez que há mais WALs para reproduzir. Um compromisso a ser decidido de acordo com a sua tolerância à indisponibilidade, não um valor universal.

#
Contínuo

O monitoramento não é uma etapa, é o ciclo que fecha o checklist

Esta lista de verificação não é uma auditoria única a ser verificada uma vez antes de entrar em produção. Uma base que dobra de volume ou tráfego que triplica torna obsoletos os benchmarks escolhidos na inicialização, muitas vezes sem erro explícito, apenas uma degradação progressiva da latência p95.

Três sinais merecem monitorização contínua. pg_stat_statements identifica solicitações que degradam com o tempo. pg_stat_activity relata consultas bloqueadas ou de execução anormalmente longa, e a proporção de conexões ativas para max_connections antecipa a saturação antes que produza erros no lado do aplicativo.

A guia Observabilidade do Studio cobre parte dessa base para qualquer projeto Aurabase, sem ferramentas de terceiros para instalar. Ele lista solicitações lentas, permite cancelar ou encerrar uma solicitação ativa por PID e exibe um indicador de saturação do pool que entra em alerta acima de 80% de uso. Em uma instância auto-hospedada, esse mesmo monitoramento é criado manualmente, com pg_stat_statements ativado e uma ferramenta de monitoramento externa conectada a ele.

#
Resumo

Folha de dicas: a lista de verificação completa

Oito configurações, na ordem em que mais compensam, com o que você precisa saber antes de tocá-las.

max_connectionsReiniciarDimensionado com base na concorrência real, não em um número redondo; absorva o restante por meio de um pooler no modo de transação.
buffers_compartilhadosReiniciar≈ 25% de RAM dedicada ao Postgres.
tamanho_de_cache_efetivoQuente≈ 50 a 75% de RAM (Postgres + cache do sistema operacional combinados).
trabalho_memQuente / sessãoCauteloso por padrão; teste para cima consulta por consulta com SET.
manutenção_trabalho_memQuenteMais generoso que work_mem; acelera VACUUM e CREATE INDEX.
autovacuum_vacuum_scale_factorQuente, por mesaMenor em tabelas grandes com muitas gravações, nunca globalmente.
checkpoint_completion_targetQuente0,9 por padrão desde PostgreSQL 14; para verificar especialmente em uma versão anterior.
bibliotecas_precarregadas_compartilhadasReiniciarDeve incluir pg_stat_statements antes de qualquer análise de consulta lenta.

Os limites citados aqui, como 150 ms e 80% de saturação do pool que o Aurabase Studio Advisor monitora, são um ponto de partida verificado por código, não uma verdade universal. Sua acusação real continua sendo o único juiz final. Para dimensionar max_connections com precisão em vez de seguir uma regra geral, o artigo dedicado detalha a fórmula e seus limites.

#
Perguntas frequentes

Perguntas frequentes

Três questões que surgem sistematicamente quando o checklist é aplicado pela primeira vez.

Devo reiniciar o Postgres depois de alterar um valor postgresql.conf?+
Depende da configuração. max_connections e shared_buffers estão no contexto "postmaster": é necessária reinicialização completa. work_mem, effective_cache_size, maintenance_work_mem e a maioria dos limites de autovacuum podem ser recarregados a quente com SELECT pg_reload_conf(); ou pg_ctl reload, sem interrupção do serviço.
Podemos desativar o vácuo automático para melhorar o desempenho?+
Não, nunca em produção. Desligá-lo não faz desaparecer o trabalho de limpeza: ele se acumula. Sem intervenção, acaba forçando um vácuo manual ou, pior, acionando o wraparound do ID da transação que torna o banco de dados somente leitura. Ajuste os limites tabela por tabela em vez de cortar o mecanismo.
Com que frequência você deve revisar esta lista de verificação?+
A cada mudança significativa no volume ou na carga, não apenas na implantação inicial. Um padrão que dobra de tamanho ou tráfego multiplicado por três torna obsoletos os pontos de partida acima. Nossa metodologia de benchmark de back-end detalha como construir um protocolo de medição repetido ao longo do tempo, em vez de uma auditoria isolada.

PRONTO PARA IMPLEMENTAR?

Seu back-end em cinco minutos.

Não é necessário cartão de crédito · 500 MB grátis · 50.000 MAU