Quando o VS code remote e o antigravity quase derrubaram meu servidor: anatomia de um thrashing de memória
Voltar para blog

Quando o VS code remote e o antigravity quase derrubaram meu servidor: anatomia de um thrashing de memória

22/09/2026 · 4 min · DevOps

Quando o servidor congelou: anatomia de um thrashing de memória#

Poucos cenários no desenvolvimento diário são tão frustrantes quanto ver um servidor travar de repente com a CPU em 100% sem uma causa óbvia no código da aplicação.

Recentemente, enfrentei um problema no meu servidor de desenvolvimento Linux: toda vez que eu abria o VS Code Remote (SSH) paralelamente à execução do binário do Antigravity, o consumo de CPU simplesmente estourava, degradando a máquina até quase congelar todo o ambiente.

Neste artigo, compartilho o passo a passo do diagnóstico: como saí da suspeita inicial de contenção de CPU, cheguei à causa raiz na gestão de memória e swap, analisei métricas reais via CLI e apliquei as correções para estabilizar o host.


1. O sintoma inicial e as primeiras hipóteses#

O sintoma era direto: abrir o VS Code Remote + Antigravity resultava em CPU batendo no teto e congelamento geral de sessões SSH.

Inicialmente, quando pensamos em CPU explodindo em ambientes com essas ferramentas, três hipóteses operacionais surgem:

  1. File Watching e Indexação do VS Code (inotify e ripgrep): O VS Code Server usa intensamente a API inotify do kernel e processos rg (ripgrep) em segundo plano para indexar a árvore de arquivos. Se o workspace tiver muitos arquivos ou diretórios pesados não ignorados (como node_modules ou .git), ele queima ciclos de processamento sem parar.
  2. Context Switching e Contenção de Threads: Em binários compilados multithreaded (como workers de processamento concorrente), um excesso de trocas de contexto faz as threads passarem mais tempo sendo escalonadas pelo kernel do que executando código útil.
  3. Garbage Collection Agressivo: Runtimes Node.js (do VS Code Server e da IDE) entrando em loops de GC constantes ao atingir o limite de heap.

Para validar essas ideias, o primeiro passo foi inspecionar o comportamento da máquina via terminal.


2. A falsa saturação de CPU: descobrindo o i/o wait#

Ao abrir o top, o consumo de CPU parecia estar em 98%, mas uma leitura atenta dos campos revelou a verdadeira causa:

%Cpu(s):  4.2 us, 38.5 sy,  0.0 ni,  1.1 id, 55.8 wa,  0.0 hi,  0.4 si,  0.0 st

O tempo de execução em espaço de usuário (us) estava em apenas 4.2%. O que estava consumindo a CPU era:

Confirmando com o vmstat 1 5:

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd  livre   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 6  4 1845248 182412  24108 412580 1420 2840  3200  4100 4810 9820  5 39  1 55  0
 5  5 1845248 179320  24108 411200 1890 3120  4100  4800 5120 11400  4 42  0 54  0

As colunas si (swap-in) e so (swap-out) estavam com milhares de blocos trafegando por segundo. O servidor estava em Memory Thrashing: a memória RAM física esgotou, o kernel começou a despejar páginas ativas para o swap no disco e, a cada tecla digitada ou evento de terminal, o sistema precisava ler do disco e gravar outra página de volta, congelando tudo.


3. Identificando os ofensores de memória#

Para mapear quais processos estavam consumindo memória residente (RSS) e empurrando o host para o swap:

ps -eo pid,ppid,pmem,rss,comm,args --sort=-rss | head -n 12

Os maiores consumidores eram:

  1. node (VS Code Server / Extension Host): Múltiplos workers consumindo mais de 1.8 GB de RSS, varrendo diretórios profundos sem filtros.
  2. antigravity-server / agentes concorrentes: Alocando buffers em memória para context caching.
  3. rg (ripgrep): Processos de busca em loop indexando arquivos temporários e logs da IDE.

4. As soluções aplicadas#

A estabilização do host exigiu intervenções em três camadas: configuração do editor, parâmetros do kernel e contenção de recursos via cgroups.

1. Blindando o file watcher do VS code#

Crie ou edite .vscode/settings.json no workspace remoto para ignorar diretórios gigantescos e evitar que o inotify e o rg saturem a memória:

{
  "files.watcherExclude": {
    "**/.git/objects/**": true,
    "**/.git/subtree-cache/**": true,
    "**/node_modules/**": true,
    "**/.gemini/**": true,
    "**/tmp/**": true,
    "**/logs/**": true
  },
  "search.exclude": {
    "**/node_modules": true,
    "**/.git": true,
    "**/.gemini": true,
    "**/tmp": true
  },
  "files.autoSave": "afterDelay",
  "files.autoSaveDelay": 2000
}

2. Otimizando a agressividade de SWAP do kernel#

O Linux vem com vm.swappiness = 60 por padrão. Para servidores de desenvolvimento que rodam editores e agentes em memória, reduza a agressividade do swap e equilibre o cache:

Edite /etc/sysctl.d/99-dev-tuning.conf:

# Reduz o uso precoce de swap no disco
vm.swappiness = 10

# Mantém cache de inodes e arquivos estável na RAM
vm.vfs_cache_pressure = 50

# Ajusta limites para gravação de dirty pages
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

Aplique imediatamente:

sudo sysctl --system

3. Configurando zram com alta prioridade#

Em vez de deixar o thrashing bater em um disco lento, configure uma camada de swap comprimido em RAM (zram) com prioridade mais alta que o swap de disco:

# Alocar 4GB de zram
sudo zramctl --find --size 4G --algorithm lz4
sudo mkswap /dev/zram0
sudo swapon /dev/zram0 -p 100

Como o zram comprime páginas diretamente na memória RAM com latência de microssegundos, páginas ociosas são compactadas sem gerar I/O de disco.

4. Limitando os agentes do antigravity com Cgroups v2#

Para evitar que execuções de subagentes paralelos consumam toda a RAM livre, execute o binário dentro de uma fatia limitada de recursos:

systemd-run --user --slice=agents.slice --property=MemoryMax=3G --property=CPUWeight=50 ./antigravity-server

Considerações práticas de contenção#

Quando seu servidor parecer saturado em 100% de CPU durante sessões de desenvolvimento remoto com agentes de IA, não assuma que a carga é estritamente computacional:

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários