Como parei de derrubar o meu n8n com webhooks do WhatsApp usando 20 linhas de PHP e SQLite (Padrão "Drop-in Buffer")
Vou compartilhar uma solução boba de tão simples, mas que me salvou esses dias e acho que pode ajudar vc, se usa n8n e evolution, a tracionar automações pesadas.
O Cenário e a Dor
Se você brinca com automação de WhatsApp (tipo Evolution API) conectada ao n8n, já deve ter passado por isso. Você lança um agente conversacional integrado com IA. O negócio dá certo e, de repente, entram centenas de mensagens de uma vez.
O que acontece? A API dispara centenas de webhooks simultâneos pro n8n. O n8n tenta engolir tudo de uma vez. A CPU da VPS vai pro teto, o event loop do Node.js chora, o servidor trava por falta de memória e o pior: você perde webhooks e deixa clientes no vácuo.
Fui caçar como a galera resolvia isso e as respostas eram sempre as mesmas: "Sobe um RabbitMQ", "Coloca um Redis na frente", "Usa Kafka".
Sinceramente? Fiquei indignado. Pra que adicionar mais 1GB de consumo de RAM e uma camada bizarra de complexidade numa VPS enxuta, só pra enfileirar uns JSONs?
A Solução "Raiz": O Amortecedor de Webhooks
Lembrei que o PHP foi literalmente desenhado para o modelo shared-nothing (nasce, processa a requisição isolada e morre) e que o SQLite faz escritas no disco em milissegundos.
Resolvi arrancar o endpoint de webhook do n8n e colocar um arquivo PHP isolado na frente para atuar como um "amortecedor" (um buffer).
O código é estupidamente simples. Ele só faz três coisas: recebe o JSON, joga no SQLite e devolve status 200 pro WhatsApp não dar timeout.
webhook.php
PHP
// Recebe o webhook cru
$payload = file_get_contents('php://input');
if (!$payload) { http_response_code(400); exit; }
// Conecta no SQLite (cria o arquivo na hora se não existir)
$pdo = new PDO('sqlite:buffer_webhooks.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Cria a tabela de fila
$pdo->exec("CREATE TABLE IF NOT EXISTS fila (
id INTEGER PRIMARY KEY AUTOINCREMENT,
payload TEXT,
status TEXT DEFAULT 'pendente',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)");
// Insere na fila e vai embora
$stmt = $pdo->prepare("INSERT INTO fila (payload) VALUES (?)");
$stmt->execute([$payload]);
// Libera a API de origem instantaneamente
http_response_code(200);
echo json_encode(['status' => 'ok', 'msg' => 'Recebido']);
Como o n8n consome isso agora?
Em vez do n8n ficar de braços abertos tomando porrada de webhooks, eu inverti a lógica.
Criei um fluxo no n8n com um Schedule Trigger rodando a cada 1 minuto. Ele vai no arquivo SQLite, faz um SELECT * FROM fila WHERE status = 'pendente' LIMIT 50, processa esses 50 leads no tempo dele (chamando a API do Gemini, fazendo RAG, etc.), e no fim faz um UPDATE mudando o status pra processado.
Por que essa arquitetura é absurda de boa?
Zero perda de dados: Se o n8n cair ou reiniciar, o PHP continua de pé recebendo os webhooks e enchendo o "baldinho". Quando o n8n volta, ele continua de onde parou.
Latência minúscula: A Evolution API (ou qualquer webhook) recebe o 200 OK em questão de 10 a 20ms. Não dá gargalo na origem.
Custo de infraestrutura cravado em zero: Não precisa subir container de mensageria. Roda em qualquer servidor web que já esteja rodando seu site.
Fica aí a reflexão: às vezes a gente fica tão cego querendo usar as ferramentas "padrão de mercado" pra microsserviços, que esquece que um script monolítico básico de 20 linhas resolve o problema de forma muito mais elegante e barata.
Alguém mais usa essas abordagens mais "limpas" pra segurar concorrência sem subir infraestrutura pesada? O que vocês costumam usar de buffer por aí?