Pare de Queimar NVMe: um playbook de durabilidade para backends pesados em IA

Por Diogo Hudson Dias
Technician in a data center rack carefully removing a 2.5-inch U.2 NVMe SSD for replacement.

Seus SSDs estão morrendo, e não é azar. É o jeito que você está escrevendo. O backend pós-LLM ficou silenciosamente pesado em escrita: embeddings, compactações de bancos vetoriais, scratchpads de agentes, logging estruturado e caches de CI. Se você não definiu um orçamento de durabilidade (DWPD/TBW) e não instrumentou a amplificação de escrita, você está apostando em mortes silenciosas e precoces de NVMe — muitas vezes em 6–18 meses.

O Hacker News passou a semana passada ressuscitando um paper clássico sobre como escrever em SSDs com eficiência. Ótimo. Mas ler não vai te salvar. Você precisa de uma política. Aqui vai um playbook de produção para CTOs que não querem trocar discos todo trimestre nem descobrir o que “media wearout indicator 0xE2” significa às 2 da manhã.

O que mudou: backends de IA viraram máquinas de escrita

Três mudanças detonaram silenciosamente os orçamentos de durabilidade dos SSDs:

  • Embeddings e reindexação: Particionar dados e (re)gerar embeddings de milhões de documentos produz gravações sequenciais de vários GB/dia; bancos vetoriais ainda acrescentam compactação.
  • Observabilidade em todo lugar: Traços em nível de token, logs estruturados e artefatos por requisição (prompts, chamadas intermediárias de ferramentas) aumentam escritas pequenas e síncronas.
  • Scratch de agentes + caching: Caches locais para saídas de modelo, re-ranking e retrieval geram rajadas de escrita e pequenos arquivos quentes que amplificam o GC interno.

Seu storage não piorou. Seus workloads sim.

A matemática da durabilidade em 5 minutos

Você não controla a física do NAND; você controla a velocidade com que o queima. Dois números importam:

  • DWPD (Drive Writes Per Day): Quantas gravações de disco inteiro por dia um drive suporta ao longo da garantia (geralmente 5 anos).
  • TBW (Total Bytes Written): O total de bytes graváveis ao longo do período de garantia.

Eles estão ligados: TBW ≈ Capacidade × 365 × Anos × DWPD.

Reality check: consumo vs corporativo

  • NVMe de consumo 1 TB: TBW frequentemente 300–600 TB → ≈0,16–0,33 DWPD por 5 anos. Tradução: ~160–330 GB/dia com segurança, não 1–2 TB/dia.
  • U.2 corporativo 3,84 TB (TLC): 1–3 DWPD → 7.000–21.000 TBW. Tradução: orçamento de 3,8–11,5 TB/dia por 5 anos, com proteção contra perda de energia.
  • SSDs “capacity” QLC: Mais baratos, mas a durabilidade normalmente é 0,2–0,8 DWPD. Não use em caminhos de escrita quentes.

Agora adicione o WAF (Write Amplification Factor): a razão entre escritas no NAND e escritas do host, tipicamente 1,2–5 em sistemas reais. Se o seu SO reporta 2 TB/dia mas o SSD registra 4 TB/dia, seu WAF é 2 — e o drive está morrendo duas vezes mais rápido do que você imagina.

Um exemplo concreto

Você roda um serviço com forte retrieval em um NVMe de consumo de 1 TB numa máquina de desenvolvedor ou nó on‑prem. As escritas do host fazem média de 1,2 TB/dia. O SMART do SSD em “Data Units Written” mostra 2,0 TB/dia. WAF ≈ 1,7.

  • DWPD efetivo = 2,0 / 1,0 = 2,0
  • TBW ≈ 600 TB (típico)
  • Vida útil esperada nesse ritmo ≈ 600 TB / 2,0 TB/dia = 300 dias

Ele falha em ~10 meses. Não é defeito — é matemática.

A política: defina um orçamento de durabilidade

Antes de afinar qualquer coisa, trace uma linha na areia para cada caixa ou volume:

  1. Orçamento de DWPD: Defina um alvo de DWPD ≤ 0,3 para NVMe de consumo; ≤ 0,8 para QLC; ≤ 1,5 para TLC corporativo (a menos que você tenha comprado peças de 3 DWPD).
  2. Meça escritas do host e WAF: Você precisa de ambos para ser honesto consigo mesmo.
  3. Classifique as fontes de escrita: Banco vetorial/índice, WAL de OLTP, logs/traços, caches/scratch, CI/CD e overlays de contêiner.
  4. Aloque um orçamento diário de bytes por classe e faça cumprir com rate limits, rotação e offload para object storage.

Meça o que o SSD enxerga

Em bare metal e na maioria das clouds

  • Escritas do SO: node_exporter (node_disk_written_bytes_total), iostat ou /sys/block/<dev>/stat.
  • Escritas no NAND do SSD: página de log SMART NVMe (nvme smart-log). Acompanhe Data Units Written e Percentage Used. Exponha no Prometheus.
  • WAF: WAF = NAND_writes / Host_writes. Alerta se > 2 por mais de 1 hora.

Em volumes gerenciados (EBS, PD, Azure Disks)

  • Acompanhe VolumeWriteBytes e VolumeWriteOps. Você não verá as escritas no NAND; trate o risco de WAF como função do padrão de workload (escritas pequenas e síncronas = ruim).
  • Prefira local NVMe instance storage para scratch quente e logs que você pode reidratar; use volumes de rede para dados duráveis com padrões amigáveis a WAL.

Decisões de arquitetura que salvam SSDs

1) Logs e traces: faça streaming, compacte e expire agressivamente

  • Defina max-size/max-files nos logs de contêiner; use um driver de logging não bloqueante (Fluent Bit/Vector) para enviar a S3/GCS com zstd nível 3–6.
  • Amostre tracing. Traços em nível de token são ótimos para depurar, não para 100% do tráfego de produção. Amostre 1–5% ou por taxa de erro.
  • Faça offload da retenção de longo prazo para object storage; mantenha no máximo 24–72h quentes no NVMe local.

2) OLTP e WAL: faça batching e comprima

  • Para Postgres, ative wal_compression=on (LZ4 se disponível) e considere políticas de synchronous_commit que reflitam as necessidades reais de durabilidade por classe de transação.
  • Use copy/ingest batching em vez de transações minúsculas; mire em rajadas de escrita de 4–16 MB.
  • Coloque arquivos tmp e paths de spill em um dispositivo de scratch separado que você esteja disposto a trocar com frequência.

3) Bancos vetoriais: escolher o índice é escolher durabilidade

  • Pré-agrupe embeddings e faça builds de índice fora do primário. Escreva uma vez, troque atomicamente.
  • Prefira índices amigáveis a disco (p.ex., variantes de DiskANN) a regravações constantes in-place. Use PQ/IVF para reduzir a pegada bruta em 4–16× antes de gravar.
  • Em stores baseados em RocksDB, limite a taxa de compactação (RocksDB RateLimiter), aumente os tamanhos de memtable/cf para absorver picos e ajuste blob files para valores grandes, reduzindo o churn de pequenas escritas.

4) Caches e scratch de agentes: separados e sacrificáveis

  • Coloque caches efêmeros em seu próprio volume ou classe de dispositivo. Se ele morrer, você não perde o nó.
  • Use tmpfs (RAM) para scratch quente sub-GB. Memória é mais barata do que SSDs mortos.
  • Defina TTL e limites de tamanho. Se o seu cache puder crescer sem limite, ele vai.

5) CI/CD e artefatos: higiene vence heroísmo

  • Limite o churn de camadas exportando o buildx cache do Docker para object storage em vez de martelar o overlayfs local.
  • Use overlay2 metacopy=on, redirect_dir=on no Linux para reduzir cópias de dados em renomes/movimentos.
  • Faça prune agressivo. Não mantenha 200 GB de camadas em notebooks de desenvolvedores com SSDs de consumo.

Ajustes de filesystem e SO que realmente importam

  • noatime (ou relatime padrão em distros modernas): evite escritas extras de metadados em leituras.
  • discard=async (ou fstrim semanal) para desempenho sustentado e menor GC interno.
  • IO scheduler: NVMe prefere none (noop). Não tente ser mais esperto que o controlador do SSD.
  • ext4 vs XFS: Ambos são bons. XFS escala bem para escritores paralelos; ext4 é previsível para workloads mistos. O que importa mais é o seu padrão de escrita.
  • Escritas grandes e alinhadas: Agrupe para ≥1 MB sempre que possível. Evite tempestades de sync de 4 KB.

Hardware que você realmente deveria comprar

  • TLC corporativo com PLP: Proteção contra perda de energia evita que escritas FUA surpresa virem caos amplificado. Pense em classe PM9A3, P5510 ou equivalente.
  • Folga de capacidade: A durabilidade aumenta efetivamente quando você deixa 20–30% de espaço livre. Over-provisioning reduz o WAF.
  • QLC só para frio: Ótimo para dados baratos e majoritariamente de leitura. Não use na sua camada de compactação, WAL ou caches.

Kubernetes e a realidade multi-tenant

  • Solicite/limite ephemeral-storage por pod. Alerta quando os nós passarem de 70% de uso efêmero; faça throttling ou evicte antes que o SSD entre em thrash.
  • Monte volumes de scratch (hostPath ou PVs locais) em dispositivos separados do volume primário do seu DB.
  • Sidecars que fazem logging verboso vão assassinar a durabilidade. Envie logs pela rede; não faça tail para disco para depois encaminhar.

Nuances de cloud: você não vê o NAND, mas ainda pode queimá-lo

Block storage gerenciado abstrai o TBW, mas você ainda paga pelos seus padrões — em throttling de IOPS, latência, custos de reindex e substituições surpresa de EBS durante janelas de manutenção.

  • Mantenha dados de escrita quentes no local NVMe instance store com checkpoint/rehidratação a partir de object storage.
  • Use perfis gp3/io2 dimensionados para o seu padrão burst-batched, não para o pior caso de pequenas escritas síncronas.
  • Faça snapshot após quiescência para evitar restores de ponto no tempo com alto churn que martelam os journals.

Observabilidade: prove que você está dentro do orçamento

Dashboards com três gráficos por dispositivo

  • Escritas do host (GB/dia)
  • “Data Units Written” do SSD (GB/dia) ou métrica proxy da cloud
  • WAF (deveria ficar em 1,1–1,8 em sistemas saudáveis com batching; alerte em 2+)

Alertas que valem acionar

  • Percentage Used > 80% no SMART de qualquer dispositivo de produção
  • Incrementos não zero de Media/CRC error
  • WAF > 2 sustentado por >30 minutos em volumes do DB primário ou do banco vetorial

Gire drives ou migre volumes antes da falha quando Percentage Used passar de 90% ou quando atributos de falha preditiva dispararem. Agende substituições como você agenda renovações de SSL — chatas e pontuais.

Padrões de design que reduzem escritas em 2–10×

  • Faça batching agressivo: Logs de tokens agregados por requisição, não por token. Micro-batches amigáveis a WAL de 4–16 MB.
  • Use object storage como seu write sink: Appends e blobs imutáveis pertencem a S3/GCS com regras de ciclo de vida. SSD local é para índices e working sets quentes.
  • Pré-compute offline: Construa índices fora de banda e depois faça a troca atômica. Evite churn de rebuild in-place ao vivo.
  • Desligue journaling acidental: Duas ou três camadas de journal (app + DB + FS) multiplicam as escritas. Saiba onde seu fsync realmente importa.
  • Memória em vez de disco para temporários minúsculos: tmpfs para ≤1–2 GB de scratch se paga em durabilidade economizada.

Realidade de custo: os preços de energia estão disparando — durabilidade é uma alavanca de custo

Na maior rede elétrica dos EUA, os preços de energia no atacado subiram 76% ano a ano. Padrões pesados de escrita não só matam SSDs; eles queimam CPU em compactação e GC, aumentam o consumo de energia e alongam janelas de reindex que batem nos seus SLOs. Disciplina de durabilidade é uma alavanca de TCO: menos substituições, menos lentidão, menos overprovisioning “só para sobreviver às terças de compactação”.

Como implementar isso em 30 dias

Semana 1: instrumentar e estabelecer baseline

  • Faça deploy de node_exporter + nvme_exporter; construa o dashboard de WAF.
  • Classifique o top‑5 de fontes de escrita por nó. Faça tagging por time/serviço.
  • Defina orçamentos de DWPD por dispositivo e crie alertas.

Semana 2: quick wins

  • Habilite wal_compression, limites de rotação de logs e compressão zstd para envio de logs/traces.
  • Mova scratch e caches para volumes dedicados; habilite tmpfs para temporários sub‑GB.
  • Faça batching de embeddings e pause rebuilds de índice ao vivo até existir um pipeline baseado em troca.

Semanas 3–4: correções estruturais

  • Implemente builds de índice fora de banda com promoção atômica.
  • Rate limiting de compactação em RocksDB/bancos vetoriais e tuning de memtable.
  • Cloud: mova caminhos de escrita quentes para instance NVMe com checkpoint para object storage.
  • Adquira SSDs TLC corporativos com PLP para nós de DB/vetoriais. Deixe 20–30% de espaço livre.

Resultado típico que vemos: redução de 2–5× nas escritas em NAND no mesmo workload, com melhorias de latência graças a um GC mais estável e menos penhascos de IO.

Trade-offs que você deve reconhecer

  • Mais memória, menos dor no disco: Usar RAM (tmpfs, memtables maiores) custa dinheiro. Paga-se em durabilidade e latência de cauda.
  • Compactação mais lenta vs. índices mais frescos: Limitar a taxa de compactação pode atrasar a visibilidade de atualizações. Aceitável para RAG e analytics, nem sempre para OLTP.
  • Risco do instance NVMe: Discos locais somem ao parar/encerrar. Você precisa automatizar checkpoints e reidratação.
  • Imposto da compressão: zstd/LZ4 consomem CPU. Geralmente é um ganho líquido quando evita thrash de disco; meça.

Ângulo nearshore no Brazil: não envie SSDs baratos para economizar trocados

Se você está montando times nearshore ou PoPs regionais no Brazil, não equipe com M.2 de consumo para cortar 15–20% de CapEx. Prazos de reposição de SSDs corporativos no Brazil podem ser de semanas, não dias, dependendo do fornecedor e da importação. Compre a mídia certa (TLC com PLP), monitore WAF e trate caches como descartáveis. Sai mais barato do que importações às pressas por causa de outages e tempo de engenharia perdido.

Em resumo

Backends da era da IA não quebraram os SSDs; eles expuseram seus padrões de escrita. Coloque um número na durabilidade, meça o WAF e mova dados com muitos appends para a camada certa. O resto é encanamento. Chato, confiável e muito mais barato do que festas surpresa de RMA.

Pontos-chave

  • Defina um orçamento de DWPD/TBW por dispositivo e alerte em WAF > 2 — durabilidade é um SLO de primeira classe.
  • Mova logs/traces para object storage, limite a retenção em disco a 24–72h e compacte com zstd.
  • Agrupe escritas (4–16 MB), habilite compressão do WAL e limite a taxa de compactações do RocksDB/bancos vetoriais.
  • Coloque caches/scratch em mídia separada e sacrificável ou em tmpfs; reserve TLC corporativo com PLP para dados primários.
  • Habilite noatime e discard=async; prefira escritas grandes e alinhadas e evite tempestades de sync de 4 KB.
  • Use instance NVMe para escritas quentes com checkpoints automatizados; mantenha dados duráveis em volumes de rede dimensionados.
  • Planeje substituições em 80–90% de “Percentage Used” — nunca espere a luz vermelha.

Ready to scale your engineering team?

Tell us about your project and we'll get back to you within 24 hours.

Start a conversation