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.
- Cinco projetos, em ordem: conexões/pooling, memória, autovacuum, índices/consultas lentas, pontos de verificação/WAL.
max_connectionseshared_buffersrequerem 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_statementsdeve ser listado emshared_preload_librariesantes que um simplesCREATE EXTENSIONcolete 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.
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).
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.
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.
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 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.
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.
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.
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.
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.
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.
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.
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_connections | Reiniciar | Dimensionado 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_compartilhados | Reiniciar | ≈ 25% de RAM dedicada ao Postgres. |
| tamanho_de_cache_efetivo | Quente | ≈ 50 a 75% de RAM (Postgres + cache do sistema operacional combinados). |
| trabalho_mem | Quente / sessão | Cauteloso por padrão; teste para cima consulta por consulta com SET. |
| manutenção_trabalho_mem | Quente | Mais generoso que work_mem; acelera VACUUM e CREATE INDEX. |
| autovacuum_vacuum_scale_factor | Quente, por mesa | Menor em tabelas grandes com muitas gravações, nunca globalmente. |
| checkpoint_completion_target | Quente | 0,9 por padrão desde PostgreSQL 14; para verificar especialmente em uma versão anterior. |
| bibliotecas_precarregadas_compartilhadas | Reiniciar | Deve 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
Três questões que surgem sistematicamente quando o checklist é aplicado pela primeira vez.