Blog / Infraestrutura
Supabase self-hosted: como reduzimos o consumo de memória do Kong

Artigo
Rodar o Supabase em infraestrutura própria dá controle total sobre os dados, mas exige atenção ao consumo de recursos. Num dos nossos ambientes, cinco stacks Supabase dividiam a mesma máquina virtual, e a memória vivia no limite. Num fim de noite, durante o build de uma aplicação, a VM travou por falta de RAM e todos os serviços dela saíram do ar.
Em resumo
- O Kong, gateway de API do Supabase, vem com
nginx_worker_processes = auto: um processo por núcleo de CPU que ele enxerga. - Numa VM com 24 vCPUs, isso dava 24 workers por stack, multiplicados por 5 stacks.
- Fixamos
KONG_NGINX_WORKER_PROCESSES=2em cada stack. Cada Kong caiu de cerca de 1,15 GB para 130 MB. - Medir por contêiner antes de aumentar a RAM evitou que o problema só fosse adiado.
O diagnóstico
A primeira tentação era aumentar a memória da VM. Antes, medimos o consumo de cada contêiner:
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}" | sort -k2 -h
Um serviço se destacou nas cinco stacks: o Kong. Cada instância usava mais de 1 GB, somando cerca de 5,9 GB só de gateways, numa VM que precisava de folga para builds.
A causa
O Kong é construído sobre o NGINX, e a configuração padrão do Kong define o número de workers como auto. Na documentação do NGINX, auto significa detectar o número de núcleos de CPU e criar um worker para cada um.
Esse padrão faz sentido num servidor dedicado ao Kong. Numa VM com 24 vCPUs, compartilhada por várias stacks, ele cria 24 processos em cada gateway, e cada processo carrega sua própria cópia de configuração, plugins e cache em memória.
A correção
A documentação do Kong permite definir qualquer parâmetro de configuração por variável de ambiente, com o prefixo KONG_. No Docker Compose de cada stack:
services:
kong:
environment:
KONG_NGINX_WORKER_PROCESSES: "2"
Para o volume de requisições desses projetos, dois workers são mais que suficientes: cada worker do NGINX atende milhares de conexões simultâneas. Depois de recriar os contêineres, dá para conferir a quantidade de processos (o esperado é 2):
docker exec <kong> sh -c "ps aux | grep -c '[n]ginx: worker'"
No nosso caso, o consumo de cada Kong caiu de cerca de 1,15 GB para 130 MB, sem perda de desempenho perceptível. Somando as cinco stacks, foram cerca de 5 GB devolvidos à VM.
O que aprendemos
- Padrões “auto” não conhecem o seu ambiente. Eles assumem que o serviço está sozinho na máquina.
- Meça por contêiner antes de aumentar a RAM. Só aumentar a memória teria adiado o problema. Também levamos a VM de 24 para 32 GB, mas para dar folga aos builds, não para alimentar o Kong.
- Reserve folga para builds. Compilações de front-end consomem muita memória por alguns minutos, e é nesse pico que o sistema trava.
- Faça backup antes de mexer. Salvamos o compose e as variáveis de cada stack antes da alteração, com o caminho de volta anotado.
Referências
- Kong Gateway: referência de configuração (
nginx_worker_processese variáveisKONG_) - NGINX: diretiva worker_processes
- Supabase: self-hosting com Docker
Precisa de ajuda com Supabase ou contêineres em produção? Fale com a gente.