Estou executando múltiplos fluxos de trabalho do n8n que leem e atualizam o PostgreSQL. Durante picos de tráfego, muitas execuções começam ao mesmo tempo e o PostgreSQL começa a mostrar alto uso de CPU e muitas conexões ativas.
Atualmente estou consultando assim: SELECT id, status
FROM orders
WHERE status = ‘pending’
ORDER BY created_at
LIMIT 100;
Estou considerando limitar a concorrência do n8n e adicionar índices: CREATE INDEX orders_pending_idx
ON orders (status, created_at);
Você priorizaria limites de concorrência do n8n, índices melhores, pooling de conexões, agrupamento em lotes, ou uma combinação desses?
Descreva o problema/erro/pergunta
Qual é a mensagem de erro (se houver)?
Por favor, compartilhe seu fluxo de trabalho
(Selecione os nós na sua tela e use os atalhos de teclado CMD+C/CTRL+C e CMD+V/CTRL+V para copiar e colar o fluxo de trabalho.)
Oi @Decoure_Ryan Eu resolveria isso com uma combinação de controle de concorrência do n8n, indexação adequada do PostgreSQL, batching e connection pooling.
O principal é não deixar o n8n enviar mais trabalho para o PostgreSQL do que o banco de dados consegue lidar confortavelmente
Controle a concorrência do n8n
Se centenas de workflows começarem ao mesmo tempo, o PostgreSQL pode ficar rapidamente sobrecarregado. Defina um limite de concorrência razoável e aumente-o gradualmente enquanto monitora o desempenho.
Torne a consulta eficiente
Seu índice é um bom começo:
CREATE INDEX orders_pending_idx
ON orders (status, created_at);
Isso ajuda o PostgreSQL a encontrar pedidos pendentes muito mais rápido.
Use lotes menores
Em vez de puxar milhares de registros de uma vez:
SELECT id, status
FROM orders
WHERE status = ‘pending’
ORDER BY created_at
LIMIT 100;
Processe um lote gerenciável e depois busque o próximo.
Use connection pooling
Se você tem muitas execuções do n8n simultâneas, o connection pooling ajuda a evitar que o PostgreSQL seja inundado com conexões.
Para resolver seus problemas de desempenho imediatos, priorize adicionar o índice composto em (status, created_at). Sua consulta atual provavelmente dispara uma varredura completa da tabela, o que causa picos de CPU conforme a tabela cresce. Implementando este índice, o PostgreSQL pode localizar instantaneamente linhas “pending” e recuperá-las na ordem correta sem o custo computacional pesado de uma classificação manual, fornecendo o alívio mais rápido para o uso da CPU.
Para resolver o erro “too many connections”, implemente um connection pooler como PgBouncer entre n8n e sua instância PostgreSQL. Como o modelo de alta concorrência do n8n tenta abrir uma nova conexão para muitas execuções simultâneas, pode rapidamente esgotar o limite de conexões do banco de dados. Usando PgBouncer no modo “transaction pooling”, centenas de fluxos de trabalho do n8n podem compartilhar um pool muito menor e estável de conexões reais de banco de dados, reduzindo significativamente a sobrecarga e prevenindo erros de conexão.
Por fim, implemente guardrails arquitetônicos combinando limites de concorrência do n8n com processamento em lote. Limitar o número de execuções simultâneas garante que, mesmo durante picos massivos de tráfego, a pressão total no banco de dados permaneça dentro de um intervalo previsível. Para escalabilidade de longo prazo, faça a transição de muitos fluxos de trabalho pequenos e frequentes para um fluxo de trabalho “mestre” que busca e processa lotes maiores de dados de uma vez, o que minimiza o número total de requisições ao banco de dados e maximiza a eficiência.
SELECT id, status
FROM orders
WHERE status = 'pending'
ORDER BY created_at
LIMIT 100
FOR UPDATE SKIP LOCKED;
CREATE INDEX orders_pending_idx
ON orders (created_at)
WHERE status = 'pending';
Adicione pool de conexões:
Coloque PgBouncer (em modo de transação) na frente do PostgreSQL ou limite o tamanho do pool de conexões do n8n (DB_POSTGRESDB_POOL_SIZE=10).
Limite a concorrência de execução:
Se estiver usando Queue Mode (Redis), defina N8N_CONCURRENCY_PRODUCTION_LIMIT=10 nos seus workers. Se estiver em instância única, processe registros sequencialmente em lotes em vez de gerar dezenas de execuções paralelas.
Oi @Decoure_Ryan
Se o n8n mantiver seus próprios dados nessa mesma instância do Postgres, parte do pico é o n8n escrevendo sobre si mesmo. Toda execução em produção insere uma linha em execution_entity e toda a carga útil da execução em execution_data, e esse volume de escrita acompanha a contagem de execuções independentemente de como a consulta de pedidos é otimizada. Verifique com SELECT pg_size_pretty(pg_total_relation_size('execution_data')); e se essa tabela dominar, pare de salvar execuções bem-sucedidas e reduza a retenção: