Diagnosticar disk IO lento no Linux com iostat e iotop

Identifique gargalos de disco no Linux usando iostat e iotop. Métricas %util, await, r/s, w/s explicadas com exemplos práticos pra sysadmins.

Aplicação lenta, load average alto e CPU mostrando 20% de uso quase sempre apontam pro mesmo culpado: disco. O sintoma clássico é uma query MySQL que normalmente roda em 50ms passar a levar 8 segundos sem mudança no plano de execução, ou um deploy de Node.js que demorava 30 segundos ficar travado em 5 minutos no npm install.

Antes de provisionar mais CPU ou RAM, você precisa confirmar que o gargalo é IO de disco. CPU baixa com load alto é o primeiro sinal — processos estão em estado D (uninterruptible sleep) esperando operações de disco. Este tutorial mostra como usar iostat e iotop pra confirmar isso em 5 minutos e identificar exatamente qual processo está saturando seu storage.

A persona aqui é o sysadmin Linux que já fez o básico (top, htop, free) e precisa cavar mais fundo. Tempo estimado de execução: 10-15 minutos pra coletar evidência conclusiva.

Pré-requisitos

Pré-requisitos

Você precisa de uma máquina Linux (Ubuntu 22.04+, Debian 12+, RHEL 9+ ou similar) com acesso sudo ou root. As ferramentas vêm em pacotes separados que não fazem parte da instalação mínima padrão.

Pacote iostat sysstat
Pacote iotop iotop
Permissão iotop root ou CAP_NET_ADMIN
Kernel mínimo 5.4+

Confirme também que CONFIG_TASK_IO_ACCOUNTING está habilitado no kernel — sem isso, iotop mostra valores zerados. Verifique com:

grep CONFIG_TASK_IO_ACCOUNTING /boot/config-$(uname -r)

A saída deve ser CONFIG_TASK_IO_ACCOUNTING=y. Em kernels custom ou containers restritos pode aparecer como # CONFIG_TASK_IO_ACCOUNTING is not set — nesse caso, use pidstat -d como alternativa.

Instalando as ferramentas

A maioria das distribuições não inclui sysstat nem iotop na instalação base. Eles ocupam menos de 5 MB combinados.

01

Instale sysstat (que fornece iostat, sar, pidstat, mpstat):

sudo apt update
sudo apt install -y sysstat

Em RHEL/Rocky/Alma:

sudo dnf install -y sysstat
02

Instale iotop:

sudo apt install -y iotop

Em RHEL/Rocky/Alma:

sudo dnf install -y iotop
03

Confirme as versões instaladas:

iostat -V
iotop --version

Versões mínimas recomendadas: sysstat 12.0+ e iotop 0.6+. Versões muito antigas têm bugs conhecidos em cálculo de %util e na coluna svctm.

Primeira leitura com iostat

iostat mostra estatísticas agregadas por dispositivo de bloco. A primeira execução mostra médias desde o boot — descarte esses números e olhe pras leituras subsequentes.

01

Rode iostat em modo estendido com intervalo de 2 segundos:

iostat -xz 2 5

Flags importantes:

  • -x — estendido, mostra todas as colunas relevantes (await, %util)
  • -z — omite dispositivos sem atividade (reduz ruído)
  • 2 5 — 5 amostras de 2 segundos cada

A primeira amostra é a média desde o boot e deve ser ignorada. Analise da segunda em diante.

02

Identifique o dispositivo de interesse na coluna Device. Em VPS modernas será algo como vda, sda ou nvme0n1. Particoes (vda1, nvme0n1p1) também aparecem mas você quer o dispositivo pai pra ver atividade total.

Interpretando as métricas

As colunas que importam pra diagnóstico estão concentradas em 6 campos. Ignore o resto até dominar esses.

MétricaSignificadoLimiar de alerta
r/sLeituras por segundo (IOPS de leitura)Depende do disco
w/sEscritas por segundo (IOPS de escrita)Depende do disco
rkB/sThroughput de leitura em KB/sCompare ao spec do disco
wkB/sThroughput de escrita em KB/sCompare ao spec do disco
awaitLatência média por requisição em ms>20ms suspeito, >100ms crítico
%util% do tempo com requisições pendentes>80% saturação em HDD
%util engana em SSD/NVMe

Em discos rotacionais (HDD), %util próximo de 100% indica saturação real. Em SSDs e NVMes que processam IO em paralelo, %util de 100% pode ocorrer com 10% da banda real em uso. Use await e compare rkB/s + wkB/s contra o spec do disco pra avaliar saturação real em mídia moderna.

A regra prática: se await está acima de 20ms num SSD ou acima de 100ms num NVMe, você tem latência anormal. Em HDDs, valores de 50-100ms já são esperados, mas acima de 200ms indica sobrecarga.

Exemplo de saída saudável

Device   r/s   w/s    rkB/s   wkB/s  await  %util
nvme0n1  142   89     8520    4310   0.42   12.30

42ms de latência num NVMe — normal. 12% util e ~12 MB/s combinados — disco respirando bem.

Exemplo de saída com gargalo

Device   r/s   w/s    rkB/s   wkB/s  await  %util
vda      890   1240   45200   78900  148.6  99.80

148ms de await é crítico — algo está fazendo muito IO sincronizado ou o disco está saturado. %util em 99.8% num disco rotacional confirma saturação. 2.130 IOPS combinados num disco que normalmente faz 200 IOPS sustentados é evidência de batch job mal-comportado ou swap thrashing.

Encontrando o processo culpado com iotop

iostat te diz QUE há gargalo. iotop te diz QUEM está causando.

01

Rode iotop em modo interativo:

sudo iotop -o

Flags:

  • -o — mostra apenas processos com IO ativo (oculta os zerados)
  • Tecla r — inverte ordenação
  • Tecla o — alterna modo “only active”
  • Tecla q — sai
02

Identifique a coluna DISK READ e DISK WRITE. Os processos no topo da lista são os maiores consumidores de IO no momento.

Coluna IO> mostra o percentual do tempo que o processo passou esperando IO. Valores acima de 30% sustentados indicam processo IO-bound — não vai ficar mais rápido com mais CPU.

03

Pra capturar evidência sem deixar o iotop rodando indefinidamente, use modo batch:

sudo iotop -o -b -n 5 -d 2 > /tmp/iotop-snapshot.txt

Isso captura 5 snapshots de 2 segundos e sai. Útil pra coletar evidência durante uma janela de lentidão reportada e analisar depois.

Alternativa quando iotop não funciona

Em containers ou kernels sem TASK_IO_ACCOUNTING, use pidstat -d 2 5 (vem no sysstat). Mostra IO por processo usando contadores diferentes que não dependem do mesmo flag de kernel.

Verificação

Pra confirmar que sua hipótese de gargalo de disco está correta, combine 3 evidências:

  1. iostat -xz 2 5 mostrando await alto e %util alto sustentados
  2. iotop -o apontando processo específico no topo da lista
  3. top ou htop mostrando processos em estado D (uninterruptible sleep) — coluna S ou STATE
ps -eo pid,state,comm | awk '$2 == "D"'

Se essa lista tem processos diferentes do PID que iotop mostrou, provavelmente são vítimas (esperando o disco liberado pelo culpado). Se for o próprio culpado, ele está fazendo IO síncrono pesado.

Resolução de problemas

iotop retorna “Could not run iotop as a non-root user”

iotop precisa de privilégios pra ler estatísticas de processos alheios. Execute com sudo. Se você quer permitir pra usuário específico sem sudo toda hora, dê a capability:

sudo setcap 'cap_net_admin+eip' $(which iotop)

iostat mostra %util de 100% mas aplicação não está lenta

Caso clássico de SSD/NVMe onde %util perdeu significado. Olhe rkB/s + wkB/s e compare com a banda nominal do disco. Se está abaixo de 50% da banda spec, não é saturação real.

Latência alta intermitente que iostat não captura

iostat mostra médias num intervalo. Picos de latência sub-segundo ficam escondidos na média. Use iostat -x 1 (intervalo 1s) durante a janela problemática, ou bpftrace pra capturar latências de bloco individuais.

Não confunda swap com IO de aplicação

Se iotop mostra kswapd0 ou [kswapd] no topo, seu sistema está em swap thrashing — sem memória RAM, kernel está movendo páginas pra disco constantemente. Solução não é otimizar IO; é adicionar RAM ou encontrar o vazamento de memória. Verifique free -h e ajuste vm.swappiness.

Próximos passos

Com o gargalo identificado, os caminhos comuns são:

  1. Aplicar tuning de IO scheduler — mq-deadline pra workloads transacionais, none pra NVMe puro
  2. Habilitar coleta histórica com sar (parte do sysstat) pra análise de tendência ao longo de semanas
  3. Investigar com bpftrace ou perf pra capturar stack traces dos syscalls de IO mais lentos
  4. Avaliar migração pra storage NVMe se o workload exige IOPS sustentado acima de 10k

Se você está colocando uma aplicação IO-intensiva em produção, uma VPS Hostini com storage NVMe local já entrega latência consistente sub-1ms — o que elimina a maior fonte de variabilidade em diagnósticos de disco.

Perguntas frequentes

%util de 100% sempre significa que o disco é o gargalo?

Não. Em SSDs e NVMe, %util reflete apenas se há alguma requisição em voo, não saturação real. Um NVMe pode mostrar 100% util e ainda estar usando 5% da banda real. Confie em await, IOPS e throughput antes de concluir saturação em mídia moderna.

Qual a diferença entre await e svctm no iostat?

await é o tempo total que uma requisição passa no sistema (fila + serviço), em milissegundos. svctm tentava medir só o tempo de serviço, mas o cálculo era incorreto em kernels modernos e foi removido em versões recentes do sysstat. Use await como métrica principal de latência.

iotop mostra zero IO mas o sistema está lento — por quê?

iotop precisa de CONFIG_TASK_IO_ACCOUNTING habilitado no kernel. Em containers e alguns kernels customizados ele aparece zerado. Confirme com cat /proc/self/io — se o arquivo não existe ou está vazio, accounting está desabilitado e você precisa usar pidstat -d ou bpftrace.

Por que await alto mas %util baixo?

Geralmente indica disco remoto com latência de rede (NFS, iSCSI, storage de nuvem) ou throttling do hipervisor em ambientes virtualizados. O disco local não está saturado, mas cada requisição demora porque vai pela rede. Verifique o tipo de storage e métricas de rede.

iostat -x mostra rrqm/s e wrqm/s altos — isso é ruim?

Não, é o oposto. rrqm/s e wrqm/s são requisições mescladas pelo kernel antes de ir ao disco — significa que o IO scheduler está combinando operações sequenciais em batches maiores e mais eficientes. Valores altos aqui geralmente indicam workload sequencial bem otimizado.

Posso rodar iotop em produção sem impacto?

Sim, o overhead do iotop é baixo (~1-2% CPU em servidores ocupados). Use iotop -o -b -n 5 -d 2 pra capturar 5 snapshots de 2 segundos em modo batch e sair — ideal pra coletar evidência sem deixar processo rodando indefinidamente.

Tópicos:
Próximos passos Cloud Ryzen com NVMe e proteção DDoS sempre ativa.Coloque em produção numa VPS Hostini →
Esse tutorial foi útil?
Falar no WhatsApp