Almacenamiento: NVMe vs SATA SSD — La prueba de carga que lo cambia todo

¿Te fue útil?

Tu aplicación se siente “lenta” y todo el mundo tiene un sospechoso favorito. El equipo de base de datos culpa a la red. El equipo de plataforma culpa a la base de datos. El proveedor dice “actualicen a NVMe”. Mientras tanto, tus paneles muestran la CPU al 20% y la memoria cómoda, pero la latencia p95 sube como si tuviera prisa.

Así se toman decisiones de almacenamiento en el mundo real: por impresiones, capturas de pantalla y la unidad que estaba en oferta. La solución es aburrida y despiadada: ejecuta una prueba de carga que se parezca a tu I/O de producción, mide las cosas correctas (percentiles de latencia, encolamiento, comportamiento del extremo de la cola) y deja que los números dicten la decisión. NVMe vs SATA SSD deja de ser religión y se convierte en aritmética.

La prueba de carga que lo cambia todo

El mayor error en los debates “NVMe vs SATA” es medir la carga equivocada. La gente ejecuta una prueba de lectura secuencial, obtiene un número enorme y declara victoria. Luego la producción sigue atorándose porque la carga real son escrituras aleatorias pequeñas con sync, o accesos mixtos con latencias de cola desagradables. Tu negocio no se rige por MB/s máximos. Se rige por tiempos de finalización predecibles.

La prueba de carga que lo cambia todo es simple:

  • Mide percentiles de latencia, no solo promedios.
  • Usa tamaños de bloque realistas (a menudo 4K–16K para bases de datos, 128K+ para streaming/backup).
  • Incluye semántica de sync si tu aplicación usa fsync/FDATASYNC.
  • Varía queue depth y concurrencia hasta ver dónde explota la latencia.
  • Ejecuta lo suficiente para alcanzar el steady state (los SSD tienen caché y comportamiento de wear-leveling; las pruebas cortas mienten).

Por qué esto cambia decisiones: los SSD SATA a menudo se ven “aceptables” a baja queue depth y poca concurrencia. Muchos sistemas de producción no son livianos. Una vez que añades concurrencia, compactación en segundo plano, checkpoints, escrituras de logs y tráfico real de usuarios, SATA alcanza un límite antes. NVMe no solo eleva el techo; cambia la forma de la curva.

Aquí está el modelo mental: SATA es un pasillo estrecho con fila de a uno. NVMe es un almacén con múltiples muelles de carga y montacargas que no comparten una sola puerta. La prueba de carga es traer suficientes camiones para ver dónde está realmente el cuello de botella.

NVMe vs SATA en la práctica (no marketing)

Protocolo y tubería: por qué existe NVMe

Los SSD SATA hablan un protocolo diseñado para discos giratorios. Funciona, pero es una capa de traducción con supuestos heredados: menos colas, menor profundidad de cola, más sobrecarga de CPU por I/O y un modelo de controlador de host optimizado para “una línea de solicitudes” y menos para “miles de operaciones concurrentes”.

NVMe se construyó para flash desde el primer día. Soporta muchas colas de envío/compra, profundidad de cola grande, menor sobrecarga y paralelismo limpio. En un servidor moderno con muchos núcleos, esto importa. El almacenamiento no es solo un dispositivo; es una canalización a través del kernel, drivers, el tejido PCIe, firmware del controlador y capas de traducción NAND. NVMe es el primer protocolo mainstream donde la canalización no finge que es 2005.

Diferencias de rendimiento que realmente notarás

Tres cosas deciden si notas la ventaja de NVMe:

  1. Latencia bajo carga: SATA puede tener latencia respetable a baja queue depth. Bajo carga, se encola más y la latencia de cola se vuelve fea más rápido.
  2. IOPS para I/O aleatorio pequeño: NVMe suele dominar aquí, suponiendo que la unidad y el sistema sean decentes.
  3. Cargas mixtas: NVMe generalmente maneja lecturas/escrituras concurrentes con menos interferencia mutua.

Y una cosa decide si no lo notarás: si estás limitado por la red, la CPU o la serialización en la aplicación, NVMe es solo una forma cara de sentirte virtuoso. Las mejoras de almacenamiento no curan malos planes de consulta.

Confiabilidad y comportamiento operativo (la parte que duele a las 3 a.m.)

Tanto NVMe como SSD SATA pueden ser fiables. Ambos pueden fallar de formas que se ven como “la app está lenta” antes de parecer “el disco está muerto”. Operativamente, NVMe te da telemetría más rica vía SMART/log pages (según las herramientas), y a menudo mejor comportamiento de latencia bajo presión. Pero también introduce modos de fallo distintos: caídas del enlace PCIe, bugs de firmware, estrangulamiento térmico y cambios en drivers del kernel que duelen durante actualizaciones.

La mayoría de los equipos subestiman la superficie operativa de “rápido”. Los dispositivos más rápidos amplifican supuestos frágiles. Si tus opciones de sistema de archivos están mal, NVMe te ayudará a llegar a la conclusión equivocada más rápido.

Hechos e historia que realmente importan

  • SATA es descendiente de ATA/IDE, una familia creada para discos duros y unidades ópticas, no para flash de baja latencia.
  • AHCI (la interfaz host común de SATA) se diseñó en la era HDD, donde las expectativas de encolamiento y paralelismo eran modestas.
  • NVMe 1.0 llegó a principios de los 2010, específicamente para evitar las ineficiencias de las pilas de almacenamiento heredadas en SSDs.
  • NVMe soporta muchas colas hardware, permitiendo mejor escalado entre núcleos de CPU; esto es importante en servidores multi-socket.
  • El comportamiento de “SLC cache” en SSDs hace que los benchmarks cortos sean deshonestos: muchas unidades de consumo y algunas enterprise funcionan rápido por ráfagas y luego se ralentizan drásticamente.
  • La escritura aleatoria 4K históricamente “los hace llorar” porque estresa las capas de traducción de flash y la amplificación de escritura.
  • TRIM/DISCARD importa: sin ello, el rendimiento sostenido puede degradarse conforme el SSD tiene menos espacio libre para gestionar.
  • El journaling de sistemas de archivos y el WAL de bases de datos se optimizaron originalmente para HDD; los SSDs cambian los trade-offs.

Métricas que deciden la discusión

Percentiles de latencia: los números adultos

La latencia media es lo que pones en una diapositiva. p95/p99/p99.9 es lo que sienten tus usuarios, lo que amplifican los reintentos y por lo que te llaman los SRE. La ventaja principal de NVMe en producción a menudo no es el rendimiento pico; es mantener la latencia de cola bajo control bajo concurrencia.

Profundidad de cola y utilización: donde aparece el cuello de botella

Cuando un dispositivo se satura, la latencia sube porque las solicitudes esperan en cola. Verás mayor await en iostat, colas más profundas en iostat -x y latencias más largas en fio. SATA tiende a saturarse antes para I/O aleatorio pequeño. NVMe también puede saturarse—todo puede—pero la rodilla de la curva suele estar más lejos.

IOPS vs ancho de banda: deja de mezclarlos

IOPS es “cuántas operaciones por segundo”. El ancho de banda es “cuánta información por segundo”. Una carga de lecturas aleatorias 4K demanda IOPS. Una carga de lecturas secuenciales de 1MB demanda ancho de banda. Si mides lo incorrecto, compras el disco equivocado.

Amplificación de escritura y estado estacionario

Los SSDs realizan garbage collection interna. Mueven datos para liberar bloques, lo que significa que el dispositivo puede escribir más de lo que le pediste. Bajo escrituras sostenidas—especialmente aleatorias—el rendimiento puede caer cuando las cachés se llenan. Cualquier benchmark que no dure lo suficiente para alcanzar el comportamiento en estado estable es básicamente una demo.

Idea parafraseada — Werner Vogels: “Diseña para el fallo; asume que los componentes se romperán y construye sistemas que sigan funcionando.”

Esto no es solo filosofía. Es ingeniería de almacenamiento: diseñas para la cola lenta, el vecino errático, el RAID degradado, la unidad que está estrangulando y el kernel que decidió cambiar valores por defecto.

Una configuración de laboratorio sensata (para no medir tu page cache)

Reglas de compromiso

  • Haz benchmarks en un dispositivo de bloque bruto o en un archivo de prueba dedicado con I/O directo, no en tu page cache.
  • Usa un tamaño mayor que la RAM. Si tu servidor tiene 64GB de RAM, no pruebes con 4GB.
  • Fija el entorno: governor de CPU, cronjobs en segundo plano, vecinos ruidosos (host de VM) y opciones de montaje del sistema de archivos.
  • Decide qué estás optimizando: throughput, latencia, latencia de cola o consistencia bajo carga.

Broma 1: Los benchmarks de almacenamiento son como las dietas: todos tienen un plan hasta que la caché actúa.

Elige cargas representativas

Unos pocos patrones cubren la mayoría de sistemas reales:

  • Base de datos OLTP: 4K–16K aleatorio lectura/escritura, mixto, concurrencia moderada a alta, comportamiento fsync/WAL.
  • Ingesta de logs: escrituras secuenciales, fsync periódico, lecturas ocasionales para indexado.
  • Hosts de VM/contenedores: I/O mixto y aleatorio a través de muchos invitados, a menudo el peor caso para latencia de cola.
  • Analítica/ETL: lecturas secuenciales grandes, algunas escrituras grandes, ráfagas.
  • Almacenamiento de objetos/Ceph: muchas operaciones pequeñas, overhead de replicación, interacción red+disco.

Tareas prácticas: comandos, salidas y la decisión que tomas

Estas son las tareas que ejecuto cuando alguien dice “el disco está lento” o “deberíamos comprar NVMe.” Cada una incluye un comando realista, una salida de ejemplo, qué significa y la decisión que impulsa.

Task 1: Identificar qué está realmente conectado (NVMe vs SATA, modelo, firmware)

cr0x@server:~$ lsblk -d -o NAME,MODEL,TRAN,SIZE,ROTA
NAME MODEL                      TRAN   SIZE ROTA
sda  Samsung_SSD_860_EVO_1TB     sata 931.5G    0
nvme0n1 Samsung_SSD_980_PRO_1TB  nvme 931.5G    0

Qué significa: Tienes dispositivos SATA y NVMe. ROTA=0 confirma SSD (no rotacional). TRAN te dice el transporte.

Decisión: Haz benchmark del dispositivo correcto y deja de discutir en abstracto. Además: registra modelo/firmware; un NVMe de consumo y un NVMe enterprise se comportan muy distinto bajo carga sostenida.

Task 2: Verificar ancho/velocidad PCIe (NVMe puede estar silenciosamente capado)

cr0x@server:~$ sudo nvme id-ctrl /dev/nvme0n1 | egrep -i 'mn|fr|rab|ieee'
mn : Samsung SSD 980 PRO 1TB
fr : 5B2QGXA7
rab : 6
ieee : 002538
cr0x@server:~$ sudo lspci -vv -s $(readlink -f /sys/class/nvme/nvme0/device | awk -F/ '{print $(NF-1)}') | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 16GT/s, Width x4
LnkSta: Speed 8GT/s (downgraded), Width x2 (downgraded)

Qué significa: El NVMe está funcionando a velocidad/anchura PCIe reducida. Esto ocurre por slots malos, opciones BIOS, risers o térmica.

Decisión: Arregla la plataforma antes de culpar al disco. Si tu “NVMe” está efectivamente en media línea, pagaste un coche deportivo y le pusiste neumáticos de bicicleta.

Task 3: Ver si el kernel piensa que tu disco está constantemente ocupado

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (server) 	02/04/2026 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.11    0.00    4.20    8.35    0.00   75.34

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz  aqu-sz  %util
sda              5.10    180.4     0.00   0.00   12.30    35.35   95.20   4200.0    10.00   9.50   45.60    44.12    4.38  99.20
nvme0n1         30.00   1200.0     0.00   0.00    0.85    40.00  110.00  5200.0     0.00   0.00    1.40    47.27    0.22  22.50

Qué significa: sda está al ~99% de utilización con write await alto; nvme0n1 va holgado. El iowait de CPU es no trivial. Esto es un cuello de botella de almacenamiento en el dispositivo SATA.

Decisión: Mueve la ruta caliente fuera de SATA, o reduce la presión de escritura (batching, menos fsyncs, mejor caché). Si los datos de la app viven en sda, NVMe en otro lado no ayudará.

Task 4: Confirmar el scheduler y ajustes de requests (especialmente para SATA)

cr0x@server:~$ cat /sys/block/sda/queue/scheduler
[mq-deadline] none
cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[none] mq-deadline kyber bfq

Qué significa: NVMe a menudo funciona mejor con none. Los SSD SATA suelen comportarse bien con mq-deadline para controlar latencia bajo contención.

Decisión: Si la latencia en SATA se dispara bajo carga, prueba mq-deadline. Si intentas “optimizar” NVMe forzando BFQ, podrías estar inventando problemas.

Task 5: Comprobar soporte TRIM/discard y si se está usando

cr0x@server:~$ lsblk -D -o NAME,DISC-GRAN,DISC-MAX,DISC-ZERO
NAME     DISC-GRAN DISC-MAX DISC-ZERO
sda            512B       2G         0
nvme0n1          4K       2G         0
cr0x@server:~$ mount | egrep ' / |/data '
/dev/nvme0n1p2 on / type ext4 (rw,relatime)

Qué significa: Los dispositivos soportan discard. Tu montaje no muestra discard; eso no es automáticamente malo. El discard en línea puede añadir jitter; fstrim periódico suele ser mejor.

Decisión: Asegura un régimen de trim (semana fstrim o equivalente). El rendimiento sostenido sin TRIM es un incidente en cámara lenta.

Task 6: Ejecutar fstrim y observar comportamiento (el jitter es una pista)

cr0x@server:~$ sudo fstrim -v /data
/data: 312.6 GiB (335657148416 bytes) trimmed

Qué significa: Se liberó espacio. Si este comando tarda “eternamente” o pica la latencia para los tenants, tu estrategia de discard puede estar peleando con la carga.

Decisión: Programa el trimming en tráfico bajo, o valida el firmware del SSD/controlador. Si el trim causa paradas notables, eso es una restricción operativa con la que debes planear.

Task 7: Detectar latencia de escritura inducida por el sistema de archivos (dirty ratios y writeback)

cr0x@server:~$ sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_expire_centisecs
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
vm.dirty_expire_centisecs = 3000

Qué significa: El kernel puede acumular muchos datos sucios antes de forzar writeback. Esto puede producir periódicos picos de latencia al hacer flush.

Decisión: Si ves “cada N segundos la app se detiene”, considera ajustar los dirty ratios o usar batching a nivel de aplicación. NVMe puede enmascararlo; no lo cura.

Task 8: Medir latencia real del dispositivo con fio (lectura aleatoria)

cr0x@server:~$ sudo fio --name=rr4k --filename=/dev/nvme0n1 --direct=1 --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=4 --runtime=60 --time_based --group_reporting
rr4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=libaio, iodepth=32
...
read: IOPS=420k, BW=1641MiB/s (1720MB/s)(98.5GiB/60001msec)
   slat (nsec): min=650, max=220k, avg=2100.3, stdev=1800.1
   clat (usec): min=45, max=3200, avg=290.4, stdev=110.2
    clat percentiles (usec):
     |  1.00th=[  90],  5.00th=[ 130], 10.00th=[ 160], 50.00th=[ 270],
     | 95.00th=[ 480], 99.00th=[ 760], 99.90th=[1200], 99.99th=[2000]

Qué significa: Fuerte IOPS de lectura aleatoria y latencia de cola respetable. Fíjate en los percentiles: p99.9 ~1.2ms. Ese es el número que importan tus servicios con alta concurrencia.

Decisión: Si tu app necesita alta concurrencia de lecturas aleatorias, NVMe está justificado. Si tu p99 en producción es peor, el cuello de botella está por encima del dispositivo (sistema de archivos, cifrado, virtualización, estrangulamiento) o la carga no es de lectura.

Task 9: Comparar con SATA usando el mismo perfil fio (y mirar la rodilla)

cr0x@server:~$ sudo fio --name=rr4k --filename=/dev/sda --direct=1 --ioengine=libaio --iodepth=32 --rw=randread --bs=4k --numjobs=4 --runtime=60 --time_based --group_reporting
rr4k: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=libaio, iodepth=32
...
read: IOPS=68.5k, BW=268MiB/s (281MB/s)(16.1GiB/60004msec)
   clat (usec): min=80, max=18000, avg=1700.2, stdev=900.4
    clat percentiles (usec):
     |  1.00th=[ 220],  5.00th=[ 420], 10.00th=[ 520], 50.00th=[1500],
     | 95.00th=[3200], 99.00th=[5200], 99.90th=[9200], 99.99th=[15000]

Qué significa: SATA se queda atrás claramente en IOPS y latencia de cola a esta carga. p99.9 acercándose a 10ms es donde los sistemas distribuidos comienzan a “ayudar” con reintentos y a empeorar la situación.

Decisión: Si tu servicio es sensible a la latencia de cola (la mayoría lo son) y trabajas con concurrencia, SATA deja de ser la opción por defecto para la capa caliente.

Task 10: Probar escrituras intensivas en sync (la comprobación de la realidad WAL/log)

cr0x@server:~$ sudo fio --name=syncwrite --directory=/data --direct=1 --rw=write --bs=4k --numjobs=1 --iodepth=1 --fsync=1 --size=2G --runtime=60 --time_based --group_reporting
syncwrite: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=psync, iodepth=1
...
write: IOPS=4800, BW=18.8MiB/s (19.7MB/s)(1.10GiB/60001msec)
    clat (usec): min=110, max=32000, avg=205.3, stdev=410.2

Qué significa: Las escrituras sync mono-hilo están limitadas por la latencia de fsync, no por la profundidad de cola. Ni siquiera NVMe convierte fsync en algo gratis; solo reduce el dolor si la unidad y la pila son buenas.

Decisión: Si estás limitado por WAL, considera: dispositivo separado para logs, group commit, tunear checkpoints o usar una unidad con protección contra pérdida de energía. No esperes que “más carriles” arreglen patrones de sync a nivel de aplicación.

Task 11: Comprobar errores de dispositivo y desgaste del medio (los fallos silenciosos también son fallos)

cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i 'Reallocated|Pending|CRC|Power_On_Hours|Wear|Media'
Power_On_Hours          17342
UDMA_CRC_Error_Count    0
Reallocated_Sector_Ct   0
Current_Pending_Sector  0
cr0x@server:~$ sudo nvme smart-log /dev/nvme0n1
Smart Log for NVME device:nvme0n1 namespace-id:ffffffff
critical_warning                    : 0x00
temperature                         : 43 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 7%
data_units_read                     : 123,456,789
data_units_written                  : 98,765,432
media_errors                        : 0
num_err_log_entries                 : 0

Qué significa: No hay errores obvios; desgaste NVMe bajo. Si ves errores de medio o entradas de log incrementadas, los incidentes de rendimiento suelen ser el acto inicial.

Decisión: Reemplaza unidades sospechosas temprano. El almacenamiento falla en dos fases: “latencia rara” y “caída”. Quieres actuar en la fase uno.

Task 12: Verificar ajustes de caché de escritura (y si te estás mintiendo)

cr0x@server:~$ sudo hdparm -W /dev/sda

/dev/sda:
 write-caching =  1 (on)

Qué significa: La caché de escritura está activada. Eso puede estar bien con SSDs, pero la durabilidad depende de la protección contra pérdida de energía del disco y del firmware.

Decisión: Para bases de datos que cuidan la durabilidad, prefiere unidades con protección contra pérdida de energía. Si no puedes garantizar eso, no “optimices” confiando en caches que no puedes razonar.

Task 13: Comprobar device mapper / sobrecarga de cifrado (común en entornos reales)

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MOUNTPOINT
nvme0n1        disk  931.5G
├─nvme0n1p1    part    512M /boot
└─nvme0n1p2    part    931G
  └─cryptdata  crypt   931G /data
cr0x@server:~$ sudo cryptsetup status cryptdata
/dev/mapper/cryptdata is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  device:  /dev/nvme0n1p2
  sector size:  512
  offset:  32768 sectors
  size:    1953499136 sectors
  mode:    read/write

Qué significa: El cifrado está en la cadena. En CPUs modernas con AES-NI, esto suele estar bien, pero puede volverse bound por CPU a alto throughput y añadir variación de latencia.

Decisión: Si los números NVMe decepcionan, revisa la utilización de CPU durante fio. Si el crypto es el cuello de botella, “comprar disco más rápido” se convierte en “comprar CPU o tunear cifrado”.

Task 14: Encontrar qué proceso causa presión I/O (para dejar de culpar “al disco”)

cr0x@server:~$ sudo iotop -o -b -n 3
Total DISK READ: 12.34 M/s | Total DISK WRITE: 145.67 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN  IO>    COMMAND
 9123 be/4  postgres    1.23 M/s   80.12 M/s  0.00 % 45.00 % postgres: checkpointer
 9050 be/4  postgres    0.00 B/s   30.45 M/s  0.00 % 20.00 % postgres: walwriter
 7711 be/4  root        0.00 B/s   25.10 M/s  0.00 % 12.00 % tar -cf /backup/data.tar /data

Qué significa: Los checkpoints y backups están generando carga de escritura significativa. Eso no es “lentitud misteriosa del almacenamiento”; es el sistema haciendo exactamente lo que pediste, en voz alta.

Decisión: Reprograma backups, ajusta checkpointing de la BD o aísla cargas en dispositivos diferentes. No compres NVMe solo para dejar que tar pelee con tu base de datos al mediodía.

Broma 2: Comprar NVMe para arreglar un job de backup ruidoso es como comprar un ascensor más rápido porque alguien sigue sosteniendo la puerta.

Tres mini-historias corporativas (anonimizadas, plausibles y dolorosas)

1) El incidente causado por una suposición errónea: “SATA SSD es básicamente NVMe para nuestra app”

La empresa estaba en migración de discos giratorios a SSDs. La historia de compras fue limpia: los SSD SATA eran más baratos, estaban disponibles y “lo suficientemente rápidos”. Alguien ejecutó una prueba rápida de throughput secuencial, vio cientos de MB/s y lo aprobó. El equipo de plataforma desplegó una nueva flota de réplicas de base de datos en SATA.

Durante dos semanas todo parecía bien—porque el tráfico era moderado. Entonces una campaña de marketing aumentó la concurrencia de lecturas. El primer síntoma no fueron “alertas de disco”. Fue la latencia p99 de la API subiendo, seguida por una ola de tormentas de reintentos entre servicios. Algunos workers basados en colas empezaron a expirar y reencolar trabajos. El sistema no se cayó de golpe; se degradó lentamente y de forma cruel, como una reunión que debería haber sido un correo.

En los hosts de base de datos, la CPU estaba baja. La memoria tenía margen. La red parecía normal. Pero iostat mostraba el dispositivo SATA clavado al 100% con await en decenas de milisegundos. Al principio en guardia sospecharon de un deploy de la aplicación. Revirtieron. Nada cambió.

La causa raíz fue la suposición equivocada: “SSD es SSD”. La carga era lecturas aleatorias pequeñas con suficiente paralelismo para saturar SATA. La latencia de cola se disparó, la aplicación reintentó y la carga se amplificó. Cuando volvieron a ejecutar el benchmark con un fio realista (randread, concurrencia, percentiles), la brecha entre SATA y NVMe no fue sutil; fue la diferencia entre estable y caótico.

Migraron las réplicas más calientes a NVMe, mantuvieron SATA para réplicas frías y jobs por lotes, y añadieron una prueba de carga estándar a la aceptación de hardware. La lección real no fue “siempre comprar NVMe”. Fue “siempre probar la carga que realmente ejecutas”.

2) La optimización que salió mal: “Habilitemos discard en línea en todas partes”

Otra compañía tenía una flota de SSDs que perdía rendimiento de escritura lentamente con el paso de los meses. Alguien identificó correctamente que el trimming no ocurría de forma fiable. La solución más rápida fue montar los sistemas de archivos con discard para que el kernel hiciera TRIM en línea.

Funcionó—en parte. El rendimiento sostenido mejoró. Pero la varianza de latencia empeoró. En ciertos hosts, cada pocos minutos la latencia p99 se disparaba y el “camino rápido” de la aplicación golpeaba paradas de 100ms. Los informes de incidentes eran frustrantes porque los picos eran cortos y el sistema se recuperaba antes de que alguien pudiera capturar un perfil limpio.

Eventualmente correlacionaron los picos con actividad de discard. El discard en línea introdujo trabajo adicional en la ruta de I/O e interaccionó mal con su carga mixta: muchas escrituras pequeñas más borrados grandes periódicos. El firmware del dispositivo lo manejó, pero el resultado operativo fue jitter.

La solución fue aburrida: quitar discard de las opciones de montaje, programar fstrim en ventanas de baja carga y monitorizar la duración del trim. El rendimiento se mantuvo y los picos de latencia desaparecieron. La “optimización” no estaba mal en principio; estaba mal en producción porque optimizó throughput sostenido y pagó con latencia de cola.

3) La práctica aburrida pero correcta que salvó el día: “Baselinamos la latencia antes de upgrades”

Esta no es dramática, por eso funcionó. Un equipo que operaba una plataforma de contenedores tenía una rutina: antes de upgrades del kernel, ejecutaban una pequeña suite de pruebas de almacenamiento en un nodo canario. No eran benchmarks heroicos—solo algunos perfiles fio representando sus PV comunes, más una comprobación rápida del estado del enlace PCIe y SMART NVMe.

Una semana, los números del canario estaban peor. Los percentiles de latencia de lectura aleatoria estaban degradados y el throughput cayó. La aplicación no cambió. El hardware no cambió. El único cambio fue el kernel nuevo. El equipo pausó el despliegue, investigó y encontró que un parámetro de driver/módulo había cambiado el comportamiento para sus NVMe de una forma que incrementaba la latencia bajo concurrencia.

Porque tenían baselines, la regresión fue obvia. Porque ejecutaron las pruebas antes del rollout, el radio de impacto fue un nodo. Ajustaron la configuración, confirmaron que las métricas volvieron a la línea base y continuaron el despliegue con confianza.

Nadie fuera del equipo lo notó. Ese es el punto. La práctica “aburrida” no fue comprar mejor hardware. Fue tratar el rendimiento de almacenamiento como un contrato y verificarlo continuamente.

Guía rápida de diagnóstico

Si tienes 15 minutos para encontrar el cuello de botella, haz esto en orden. No seas ingenioso. Sé rápido y correcto.

Primero: prueba que es latencia de almacenamiento (no CPU, no red, no locks)

  • Revisa la latencia p95/p99 de la app y las tasas de error. Busca reintentos/timeouts.
  • En el host: iostat -xz 1 y observa %util y await.
  • Revisa vmstat 1 por alto wa (iowait) y la cola de ejecución.

Segundo: encuentra qué dispositivo y qué proceso

  • lsblk para mapear montajes a dispositivos.
  • iotop -o para identificar los mayores escritores/lectores.
  • pidstat -d 1 si necesitas tasas I/O por proceso sin herramientas interactivas.

Tercero: decide si es saturación, mala configuración o degradación

  • Saturación: %util cerca de 100%, await en aumento, aqu-sz profundo. Arregla moviendo la carga, añadiendo dispositivos o reduciendo I/O.
  • Mala configuración: scheduler equivocado, RAID mal configurado, throttles de virtualización, overhead de cifrado, opciones de montaje. Arregla la pila.
  • Degradación: errores SMART, logs NVMe, throttling térmico, enlace PCIe degradado. Reemplaza o arregla hardware/firmware.

Cuarto: valida con una prueba fio dirigida

Ejecuta un perfil fio corto que coincida con tu dolor: ¿lectura aleatoria bajo concurrencia? ¿escrituras sync? ¿mixto 70/30? Usa --direct=1 y captura percentiles. Si la prueba del dispositivo va bien pero la producción va mal, el cuello de botella está por encima de la capa de bloque.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: “NVMe está instalado pero el rendimiento parece SATA”

Causa raíz: enlace PCIe degradado (x1/x2, menor GT/s), slot equivocado, ahorro de energía BIOS o un lane compartido del chipset.

Solución: Revisa lspci -vv estado del enlace; mueve el dispositivo a un slot conectado a la CPU; ajusta BIOS; verifica cables/risers; retesta.

2) Síntoma: “fio se ve increíble, producción aún está lenta”

Causa raíz: El benchmark usó page cache o una carga poco realista; producción es sync-heavy o mixta; throttles de virtualización o límites de cgroup.

Solución: Usa --direct=1, tamaño > RAM, y una carga que coincida con tu app. Revisa límites I/O de cgroups y políticas del hypervisor.

3) Síntoma: picos periódicos de latencia cada segundos/minutos

Causa raíz: tormentas de writeback (dirty ratios), ráfagas del journal del sistema de archivos, checkpoints de base de datos o jitter por discard en línea.

Solución: Ajusta writeback, cambia parámetros de checkpoint de BD, quita discard y usa fstrim programado, o aísla logs.

4) Síntoma: alto iowait pero baja utilización de disco

Causa raíz: estás esperando otra cosa: almacenamiento en red, stalls de firmware del controlador, capas de device mapper o ruta de locks del sistema de archivos sobrecargada.

Solución: Confirma la ruta real del dispositivo. Para almacenamiento en red, mide latencia de red y estadísticas del servidor. Para local, revisa dmesg por resets y errores.

5) Síntoma: “Actualizamos a NVMe y empeoró la latencia p99”

Causa raíz: scheduler/ajustes diferentes, throttling térmico, regresión de firmware o mayor concurrencia que revela contención a nivel de aplicación.

Solución: Revisa temperatura y throttling; compara percentiles de fio bajo carga controlada; limita concurrencia; revisa configuración de la BD. Los discos más rápidos pueden convertir locks en el nuevo cuello de botella.

6) Síntoma: throughput sostenido de escritura colapsa después de unos minutos

Causa raíz: agotamiento de SLC cache y comportamiento en estado estable; unidad sobrellenada; falta de TRIM; unidad de consumo bajo carga write enterprise.

Solución: Deja espacio libre (overprovisioning), asegura TRIM, elige un SSD enterprise con endurance y rendimiento de escritura consistente, ejecuta tests largos antes de comprar.

Listas de verificación / plan paso a paso

Paso a paso: elegir NVMe vs SATA para un servicio nuevo

  1. Clasifica la carga: OLTP DB, ingesta de logs, host de VM, analítica, almacenamiento de objetos.
  2. Elige 2–3 perfiles fio que la representen (tamaño de bloque, mix, concurrencia, semántica sync).
  3. Ejecuta en hardware candidato con el mismo kernel, sistema de archivos, cifrado y opciones de montaje que desplegarás.
  4. Registra percentiles (p95/p99/p99.9), no solo IOPS/BW.
  5. Encuentra la rodilla: incrementa iodepth/numjobs hasta que la latencia de cola se dispare. Esa es la frontera de tu región operativa segura.
  6. Mapea resultados a SLOs: si tu app necesita p99 < 5ms bajo carga, y SATA te da p99.9 de 20ms a concurrencia realista, la decisión está tomada.
  7. Decide niveles: NVMe para datos calientes y logs; SATA SSD para warm/cold, backups, batch, réplicas.
  8. Operationaliza: pruebas baseline en canarios, monitorización SMART/NVMe logs, calendario de trim, gestión de firmware.

Paso a paso: retroadaptar un sistema existente lento

  1. Ejecuta iostat -xz 1 y iotop -o durante la ventana del incidente.
  2. Mapea el montaje caliente al dispositivo con lsblk.
  3. Busca jobs en segundo plano (backup, compaction, scrubs).
  4. Revisa salud del dispositivo (SMART/NVMe logs) y estado del enlace PCIe (NVMe).
  5. Ejecuta un test fio dirigido que coincida con el patrón sospechado en el dispositivo afectado.
  6. Si fio está bien pero la prod va mal: mira por encima de la capa de bloque (sistema de archivos, cifrado, config BD, cgroups, hypervisor).
  7. Aplica el cambio más pequeño que elimine el cuello de botella: mover WAL, aislar backups, ajustar checkpoints o migrar datos calientes a NVMe.
  8. Vuelve a probar y registra una baseline para que el próximo incidente sea más corto.

Checklist operativo: qué monitorizar continuamente

  • Latencia p95/p99 en los límites del servicio; tasas de reintento.
  • Disk await, %util, tamaño de cola y mix lectura/escritura por dispositivo.
  • NVMе SMART: temperatura, porcentaje usado, errores de medio, entradas en el log de errores.
  • Espacio libre del sistema de archivos y éxito de trim.
  • Timing de jobs en segundo plano: backups, compactions, scrubs.

FAQ

1) ¿NVMe es siempre más rápido que un SSD SATA?

No siempre en la forma que te importa. Para baja concurrencia y cargas simples, SATA puede ser “suficientemente rápido”. Bajo I/O aleatorio paralelo y cargas mixtas, NVMe normalmente gana—especialmente en latencia de cola.

2) ¿Por qué mi benchmark secuencial muestra diferencias pequeñas, pero mi base de datos va mucho más rápido en NVMe?

Porque las bases de datos rara vez son secuenciales. Hacen lecturas/escrituras pequeñas aleatorias, escrituras sync para logs y patrones de acceso mixtos. El modelo de colas de NVMe y su menor sobrecarga ayudan donde realmente vive la base de datos.

3) ¿Qué opciones de fio evitan que mida la page cache?

Usa --direct=1, y asegúrate de que el tamaño de la prueba exceda la RAM si estás usando un archivo. Para dispositivos crudos, usa la ruta del dispositivo y ten cuidado de no sobrescribir datos reales.

4) ¿Qué profundidad de cola debo probar?

Prueba un rango: 1, 4, 16, 32, 64—más la concurrencia realista (numjobs). Buscas la rodilla donde los percentiles de latencia se disparan. Esa rodilla suele ser el límite de capacidad que importa en producción.

5) ¿Puede SATA SSD ser la elección correcta en producción?

Sí: tiers cálidos, servicios de solo lectura con baja concurrencia, caches, réplicas, pipelines por lotes y staging de backups. También está bien cuando el cuello de botella está en otro sitio y lo has probado con medición.

6) ¿Necesito protección contra pérdida de energía (PLP) en NVMe?

Si te importan garantías de durabilidad (bases de datos, sistemas de archivos con semánticas estrictas), PLP es muy recomendable. Sin ella, podrías estar confiando en caches volátiles más de lo que crees.

7) ¿Por qué el rendimiento empeora cuando el disco está casi lleno?

Los SSD necesitan bloques libres para garbage collection y wear leveling. Menos espacio libre significa más copias internas y mayor amplificación de escritura. Mantén margen y trim correctamente.

8) ¿Vale la pena separar WAL/logs en NVMe mientras los datos quedan en SATA?

A menudo sí. WAL y logs son sensibles a la latencia y sync-heavy. Poner logs en un dispositivo más rápido y de menor latencia puede mejorar la latencia de commit y reducir la contención. Pruébalo—no lo asumas.

9) ¿Cómo sé si estoy bound por CPU debido al cifrado en lugar de por disco?

Ejecuta fio y observa la utilización de CPU. Si el throughput topea mientras el disco no está ocupado y la CPU está alta en paths de kernel/crypto, estás bound por CPU. Considera CPUs más rápidas, tunear o offload hardware según tu entorno.

Pasos prácticos siguientes

Haz tres cosas esta semana:

  1. Escribe tu carga en un párrafo: tamaño de bloque, mix lectura/escritura, requisitos de sync y concurrencia esperada. Si no puedes describirla, no puedes comprar hardware para ella.
  2. Crea una pequeña suite fio (2–4 jobs) y ejecútala en un SSD SATA y en un NVMe en tu entorno. Captura latencias p95/p99/p99.9.
  3. Establece una baseline y protégela: ejecuta la suite en un canario antes de cambios de kernel/firmware. Las regresiones de almacenamiento son sigilosas; las baselines las hacen ruidosas.

Si construyes servicios sensibles a la latencia o ejecutas hosts multi-tenant, por defecto usa NVMe para la ruta caliente y justifica SATA solo cuando la medición lo pruebe. Si gestionas tiers cálidos/fríos, backups o cargas de baja concurrencia de lectura, SATA puede ser una elección racional por coste. En cualquier caso, la prueba de carga termina la discusión — y evita que envíes un incidente de almacenamiento como si fuera una característica.

← Anterior
Historias de bloqueo por proveedor (y cómo escapar limpiamente)
Siguiente →
Conflicto de IP detectado: encuentra al culpable rápido

Deja un comentario