>_ josetilabs.com
← blog

27 out 2026 · linux, disco, benchmark · 4 min

Como medir a velocidade do disco sem derrubar o servidor

A regra de ouro: nunca meça disco com cache do sistema operacional, porque você mede RAM, não disco. A segunda: nunca rode teste de carga no disco do servidor de produção. Este post entrega um script que mede escrita e leitura sequencial, IOPS aleatório e latência, com arquivo de teste pequeno e limpeza automática.

Terminal mostrando o benchmark do disco com escrita sequencial 159 MB/s, leitura sequencial 968 MB/s, random read 4K de 7700 IOPS e random write com fsync de 416 IOPS
Medição real com O_DIRECT: escrita 159 MB/s, leitura 968 MB/s, random read 7700 IOPS, random write com fsync 416 IOPS.

O que medir, e o que não

Quatro números respondem 90% das perguntas sobre disco:

  1. Escrita sequencial: quanto o disco engole quando você grava um arquivo grande de uma vez. Importa para backup, cópia de imagem, log rotacionado.
  2. Leitura sequencial: quanto ele entrega lendo um arquivo grande. Importa para restauração de backup, leitura de dump.
  3. IOPS aleatório de leitura: quantas operações de 4 KB por segundo ele sustenta lendo blocos espalhados. Importa para banco de dados, índice de busca, cache em disco.
  4. Latência de escrita com fsync: quanto tempo leva uma escrita pequena seguida de fsync. Importa para qualquer coisa que promete “durável” (banco, fila, journal).

O script

Salve como medir-disco.sh, torne executável com chmod +x medir-disco.sh e rode com ./medir-disco.sh. Por padrão ele usa 16 MB de arquivo de teste, o que roda em qualquer máquina e em contêiner com pouco espaço. Mude SIZE_MB para 64 ou 128 se quiser medir o disco de verdade, e nunca além do espaço livre.

bash
#!/usr/bin/env bash
set -euo pipefail

# medir-disco.sh
# Mede escrita e leitura sequencial e IOPS aleatório de leitura.
# Limites: arquivo de teste pequeno por padrão, limpeza automática, sem tocar no SO.
# Uso: SIZE_MB=64 ./medir-disco.sh

DIR="${DIR:-/tmp/disco-teste}"
SIZE_MB="${SIZE_MB:-16}"
BS="1M"

mkdir -p "$DIR"
FILE="$DIR/teste.bin"

echo "arquivo de teste: ${SIZE_MB} MB (O_DIRECT via dd)"

# Escrita sequencial, com fsync ao final: força o dado a ir para o disco.
echo "--- escrita sequencial ---"
dd if=/dev/zero of="$FILE" bs="$BS" count="$SIZE_MB" conv=fdatasync status=none
# repete para pegar a taxa (a primeira passada aquece cache e metadados)
dd if=/dev/zero of="$FILE" bs="$BS" count="$SIZE_MB" conv=fdatasync status=progress 2>&1 | tail -1

# Leitura sequencial, bypass de cache do SO.
echo "--- leitura sequencial ---"
dd if="$FILE" of=/dev/null bs="$BS" iflag=direct status=progress 2>&1 | tail -1

# Limpeza: o arquivo de teste não fica para trás.
rm -f "$FILE"
rmdir "$DIR" 2>/dev/null || true
echo "limpo: $FILE removido"

O conv=fdatasync força o kernel a esperar o dado chegar ao disco antes de terminar; sem ele, o dd termina quando o dado entra no cache de escrita do SO e o número mente. O iflag=direct na leitura bypassa o cache de leitura.

Para IOPS aleatório e latência de fsync, use o bloco abaixo em Python, que roda em qualquer máquina com Python 3:

python
import os, time, random, statistics

p = "/tmp/disco-rand.bin"
size = 16 * 1024 * 1024
with open(p, "wb") as f:
    f.write(os.urandom(size)); f.flush(); os.fsync(f.fileno())

# random read 4K
fd = os.open(p, os.O_RDONLY)
lat = []
t0 = time.perf_counter()
for _ in range(1000):
    os.lseek(fd, random.randrange(0, size - 4096, 4096), os.SEEK_SET)
    s = time.perf_counter(); os.read(fd, 4096)
    lat.append((time.perf_counter() - s) * 1000)
os.close(fd)
print(f"random read 4K: {1000 / (time.perf_counter() - t0):.0f} IOPS, p99 {sorted(lat)[989]:.2f} ms")

# random write 4K com fsync por operação
fd = os.open(p, os.O_RDWR)
latw = []
t0 = time.perf_counter()
for _ in range(300):
    os.lseek(fd, random.randrange(0, size - 4096, 4096), os.SEEK_SET)
    s = time.perf_counter()
    os.write(fd, os.urandom(4096)); os.fsync(fd)
    latw.append((time.perf_counter() - s) * 1000)
os.close(fd)
print(f"random write 4K fsync: {300 / (time.perf_counter() - t0):.0f} IOPS, p99 {sorted(latw)[296]:.2f} ms")

os.remove(p)

Como verificar

Rode o script e confira três coisas:

Medição real: escrita 159 MB/s, leitura 968 MB/s, random read 7700 IOPS, random write 416 IOPS. Leitura em cache: 8355 MB/s.

Se der errado

dd, fio ou Python: qual usar

Ferramenta O que mede bem O que mede mal Quando usar
dd taxa sequencial grande IOPS, latência primeiro teste, qualquer máquina
fio tudo: IOPS, latência, padrão de acesso configurável nada, mas a sintaxe é densa quando o dd não responde à pergunta
Python com os.O_DIRECT IOPS e latência de leitura, fsync por operação taxa sequencial grande quando você quer medir o que o banco sente
cp / rsync nada reproduzível tudo nunca para medir

O fio é a ferramenta certa para benchmark sério: ele separa leitura e escrita, aleatório e sequencial, e reporta percentis de latência. A sintaxe mínima para o mesmo teste deste post é fio --name=teste --size=64m --rw=randread --bs=4k --direct=1 --runtime=30. Instale com o gerenciador de pacotes da sua distribuição (apt install fio, dnf install fio); não rode como root se puder evitar.

FAQ

Por que a primeira passada de escrita é mais lenta? O sistema de arquivos está alocando blocos e atualizando metadados. A segunda passada mede só o disco. Por isso o script escreve duas vezes e você lê a segunda.

O número do fabricante é maior que o meu. Por quê? O fabricante mede em condições ideais: fila profunda, cache quente, sem concorrência, sem sistema de arquivos. Seu número inclui sistema de arquivos, journaling e concorrência real. Os dois estão certos; são perguntas diferentes.

O resultado muda muito entre execuções? Em SSD, sim, por causa de cache interno e coleta de lixo. Rode três vezes e use a mediana. Em disco mecânico, o número é estável.

Fontes: dd(1), fio(8). Links internos: disco cheio: como achar o que está ocupando, o que são cgroups, ver o que come a RAM.

Leia também

// Por e-mail

Os textos publicados aqui também vão por e-mail. O envio ainda não começou: quem deixar o endereço agora entra na primeira lista.

Guardo só o seu e-mail, a data e o registro desta autorização. Sem cookies, sem rastreador e nada compartilhado com terceiros. Detalhes na política de privacidade.