Es el clásico: parcheas una máquina Ubuntu que funcionaba perfectamente, reinicias y de repente tu sistema “ágil” parece intentar correr dentro de cemento húmedo. Los paneles se traban. Los despliegues se arrastran. Las gráficas de E/S parecen un monitor cardiaco. Tu primer impulso es culpar “la actualización” como un monstruo difuso. Eso satisface emocionalmente. También es inútil operativamente.
Las regresiones de rendimiento son normalmente uno o dos cuellos de botella concretos disfrazados. El trabajo es capturarlos rápido, identificar si son regresiones reales o solo cambios de por defecto distintos, y tomar una decisión fría: revertir, ajustar o esperar a un arreglo upstream.
Plan rápido de diagnóstico (qué comprobar primero)
Si solo tienes 15 minutos antes de que te vuelvan a pedir, haz esto en orden. La idea no es recolectar datos para un museo. La idea es identificar la clase de cuello de botella: CPU, presión de memoria, latencia de disco, red o “un servicio nuevo se está comiendo el host”.
1) Confirma qué cambió (kernel, microcode, controladores, servicios)
- Comprueba el kernel actual y la hora del último arranque.
- Enumera las actualizaciones de paquetes recientes y las unidades nuevas habilitadas.
- Busca nuevas actualizaciones de snap si ejecutas sistemas con mucho snap.
2) Clasifica la ralentización: ¿CPU, E/S o memoria?
- Si la carga es alta y
iowaites alto, normalmente es almacenamiento o comportamiento del sistema de archivos. - Si la CPU está al máximo en user/system con bajo
iowait, es un proceso desbocado, una tormenta de syscalls o un demonio “útil” nuevo. - Si ves mucha actividad de swap, hay presión de memoria o una regresión en el working set.
3) Identifica el proceso principal culpable y confirma que se correlaciona con la ralentización
- No te quedes en “top dice X usa CPU”. Comprueba si está bloqueado en disco o esperando locks.
4) Mide la latencia de disco (no el throughput) y el encolamiento
- El throughput puede parecer correcto mientras la latencia destruye el rendimiento de cola larga.
- Confirma si es un dispositivo, un sistema de archivos o una opción de montaje concreta.
5) Revisa el escalado de frecuencia de la CPU y los perfiles de energía
- Tras las actualizaciones, los valores por defecto relacionados con energía y los controladores pueden cambiar. Si la CPU está atascada en powersave, todo se siente “misteriosamente lento”.
6) Solo entonces: profundiza en logs del kernel, regresiones de controladores, denegaciones AppArmor y crecimiento de journald/logs
- Estos son comunes en Ubuntu 24.04 porque la plataforma es moderna y activa: nuevos kernels, nuevos controladores y nuevas políticas.
Una idea parafraseada de Gene Kim (autor DevOps) que los equipos de operaciones deberían tatuar en sus runbooks: optimiza para detección rápida y recuperación rápida, no para prevención perfecta.
Esa mentalidad es como te mantienes cuerdo durante la temporada de “se puso lento”.
Las primeras 6 comprobaciones que suelen revelar al culpable
Comprobación 1: ¿Realmente estás ejecutando el kernel que crees?
Tras actualizaciones, “actualizamos” y “estamos ejecutando el kernel actualizado” no son la misma afirmación. Si usas Livepatch, múltiples kernels o reinicios diferidos, puedes estar en un estado medio donde el userland espera un comportamiento y el kernel entrega otro. También: un nuevo kernel puede haber cambiado una ruta de controlador (NVMe, red, GPU), y ahora sufres una regresión.
Comprobación 2: ¿El sistema está limitado por E/S (iowait, latencia de disco, profundidad de cola)?
Las regresiones de E/S son la principal fuente de quejas de “la máquina entera está lenta” porque afectan todo: arranque, instalaciones de paquetes, commits de bases de datos, reinicios de servicios, escrituras de logs. Tras una actualización, los desencadenantes comunes incluyen:
- Opciones de montaje del sistema de archivos cambiadas u “mejoradas”.
- El volumen de journald aumentó y ahora hace más sincronizaciones.
- Refrescos de snap que se inician en momentos inconvenientes.
- Cambios en el controlador de almacenamiento (NVMe/APST, scheduler, multipath).
Comprobación 3: ¿La presión de memoria está forzando reclaim o swap?
Ubuntu 24.04 funciona bien en hardware moderno, pero tu carga puede no hacerlo. Una actualización de paquete puede cambiar tamaños de cache por defecto, introducir un servicio nuevo o actualizar un runtime que aumente la memoria. Una vez que entras en reclaim sostenido, verás lentitud “aleatoria”: todo espera detrás de la gestión de memoria.
Comprobación 4: ¿Cambió el escalado de frecuencia/perfil de energía de la CPU?
En portátiles es obvio. En servidores es más sigiloso. Un cambio en perfiles de energía, configuración BIOS, microcode o comportamiento del controlador puede mantener los núcleos a baja frecuencia bajo carga u oscilar. Parece “la CPU está al 40% pero las peticiones son lentas”.
Comprobación 5: ¿Se habilitó, reconfiguró o empezó a thrashar algún servicio?
Systemd facilita habilitar cosas. Las actualizaciones también pueden cambiar los valores por defecto de las unidades. Un demonio pequeño que hacía “solo un poco de escaneo” se convierte en un rastreador constante de disco en sistemas de archivos grandes. Los sospechosos habituales: indexadores, agentes de seguridad, hooks de backup, shippers de logs y cualquier cosa que “descubra” imágenes de contenedores.
Comprobación 6: ¿Los logs del kernel muestran errores, reinicios o denegaciones de políticas?
Si el rendimiento se desplomó, a menudo es porque el sistema está reintentando algo. Enlaces que se caen. Reinicios NVMe. Advertencias del sistema de archivos. AppArmor deniega una ruta caliente, provocando reintentos y comportamientos extraños. Los logs del kernel son donde está enterrado el cuerpo.
Broma #1: Lo único más consistente que “se puso lento tras la actualización” es “ya estaba lento, la actualización solo hizo que la gente lo notara”.
Tareas prácticas: comandos, interpretación y decisiones (12+)
Estas son las tareas que ejecuto en cajas de producción reales porque responden preguntas rápidamente. Cada tarea incluye: un comando, qué significa la salida y la decisión que tomas. Ejecútalas como usuario con sudo donde sea necesario.
Task 1: Confirmar kernel, tiempo de arranque y plataforma básica
cr0x@server:~$ uname -a
Linux server 6.8.0-41-generic #41-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
cr0x@server:~$ uptime -s
2025-12-29 02:14:03
Significado: Ves exactamente qué kernel está activo y cuándo se arrancó. Si la actualización ocurrió pero uptime es anterior, no reiniciaste y en realidad no estás probando el kernel actualizado.
Decisión: Si la regresión empezó solo después del reinicio, sospecha del kernel/controlador/servicios. Si empezó antes del reinicio, sospecha actualizaciones de userspace o tareas en segundo plano (refrescos de snap, indexadores, crecimiento de logs).
Task 2: Listar actualizaciones recientes para correlacionar el “inicio de la ralentización”
cr0x@server:~$ grep -E " upgrade | install " /var/log/dpkg.log | tail -n 15
2025-12-28 21:05:12 upgrade linux-image-6.8.0-41-generic:amd64 6.8.0-40.40 6.8.0-41.41
2025-12-28 21:05:20 upgrade linux-modules-6.8.0-41-generic:amd64 6.8.0-40.40 6.8.0-41.41
2025-12-28 21:06:01 upgrade systemd:amd64 255.4-1ubuntu8 255.4-1ubuntu9
2025-12-28 21:06:29 upgrade openssh-server:amd64 1:9.6p1-3ubuntu13 1:9.6p1-3ubuntu14
Significado: Muestra qué cambió recientemente. Actualizaciones de kernel y systemd son sospechosas de alto impacto porque tocan arranque, gestión de dispositivos, cgroups y comportamiento de logging.
Decisión: Elige 1–3 actualizaciones “más sospechosas” y revisa su changelog respecto a tu entorno (especialmente kernel y pila de almacenamiento/red).
Task 3: Revisar systemd por unidades fallidas y servicios lentos en el arranque
cr0x@server:~$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● fwupd.service loaded failed failed Firmware update daemon
cr0x@server:~$ systemd-analyze blame | head
35.114s snapd.seeded.service
12.892s dev-nvme0n1p2.device
8.310s systemd-journald.service
6.942s NetworkManager-wait-online.service
Significado: Unidades fallidas pueden causar bucles de reintento. La salida de blame muestra qué está consumiendo tiempo de arranque; también es una pista sobre lentitud en tiempo de ejecución (por ejemplo, journald tardando, dispositivos lentos en aparecer).
Decisión: Si una unidad falla o se reinicia, arréglala primero. Si snapd seeding domina y coincide con la ralentización, probablemente tienes churn de E/S en segundo plano.
Task 4: Identificar los mayores consumidores actuales (CPU, memoria) sin adivinar
cr0x@server:~$ ps -eo pid,comm,%cpu,%mem,etimes,state --sort=-%cpu | head -n 12
PID COMMAND %CPU %MEM ELAPSED S
2143 node 280.5 6.1 15421 R
982 systemd-journal 32.1 0.3 86322 R
1777 snapd 24.8 0.6 74210 S
1460 postgres 18.2 12.4 99111 S
Significado: Obtienes una lista ordenada, con tiempo transcurrido y estado. “R” significa en ejecución; “D” (uninterruptible sleep) a menudo significa atascado en E/S.
Decisión: Si un proceso está agotando la CPU, profundiza en él. Si muchos procesos importantes están en “D”, deja de culpar la CPU y ve al almacenamiento.
Task 5: Comprobar carga, iowait y cambios de contexto
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 10240 812344 92160 6123456 0 0 112 205 3210 5400 18 6 70 6 0
6 3 10304 92344 90240 5943120 40 88 9800 6100 5400 8800 22 9 40 29 0
4 2 10496 74320 90112 5901220 52 140 10400 7200 5900 9400 18 10 41 31 0
7 4 10560 70212 90224 5899900 60 160 12000 8400 6100 9900 16 11 38 35 0
3 1 10560 69300 90240 5898000 0 0 2100 1900 4100 7200 14 8 70 8 0
Significado: Observa wa (I/O wait) y swap in/out (si/so). Actividad de swap sostenida significa presión de memoria. wa alta sostenida indica latencia/encolamiento de almacenamiento.
Decisión: Swap alto: arregla la memoria (reduce working set, añade RAM, ajusta caches). Iowait alto: mide la latencia del disco y encuentra el dispositivo o montaje causante.
Task 6: Medir latencia y utilización del disco por dispositivo (el detector de verdad)
cr0x@server:~$ iostat -xz 1 3
Linux 6.8.0-41-generic (server) 12/29/2025 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
19.20 0.00 7.10 28.40 0.00 45.30
Device r/s w/s rKB/s wKB/s await aqu-sz %util
nvme0n1 120.0 310.0 6400.0 41000.0 18.40 6.20 98.00
sda 0.0 2.0 0.0 48.0 1.10 0.01 0.20
Significado: await es la latencia media de E/S. aqu-sz y %util muestran encolamiento y saturación. Un dispositivo al ~98% de uso con await en ascenso es un cuello de botella.
Decisión: Si el disco principal está saturado, encuentra qué está leyendo/escribiendo y si es esperado (carga DB) o nuevo (tormenta de logs, refresh de snap, indexación, agente de backup).
Task 7: Atribuir las E/S de disco a procesos (quién está golpeando el disco)
cr0x@server:~$ sudo iotop -oPa
Total DISK READ: 28.40 M/s | Total DISK WRITE: 41.10 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
982 be/4 syslog 0.00 B/s 9.50 M/s 0.00 % 95.00% systemd-journald
1777 be/4 root 0.00 B/s 7.20 M/s 0.00 % 80.00% snapd
2143 be/4 app 6.10 M/s 2.40 M/s 0.00 % 35.00% node /srv/app/server.js
Significado: Ves qué procesos están haciendo E/S real ahora mismo. IO> alto sugiere que el proceso pasa tiempo esperando E/S en lugar de ejecutar.
Decisión: Si journald escribe mucho, inspecciona la tasa de logs y la configuración de persistencia. Si snapd escribe mucho durante refresh/seeding, programa o controla las ventanas de refresh.
Task 8: Comprobar tamaño y tasa de journald (las tormentas de logs son tormentas de rendimiento)
cr0x@server:~$ journalctl --disk-usage
Archived and active journals take up 6.2G in the file system.
cr0x@server:~$ sudo journalctl -p warning -S "1 hour ago" | tail -n 8
Dec 29 09:12:41 server kernel: nvme nvme0: I/O 123 QID 7 timeout, aborting
Dec 29 09:12:43 server kernel: nvme nvme0: Controller reset, clearing queue
Dec 29 09:12:44 server systemd-journald[982]: Missed 312 log messages due to rate-limiting
Significado: Grandes journals no son automáticamente malos, pero el churn intenso sí. Además, advertencias sobre timeouts de dispositivo se correlacionan fuertemente con picos de latencia.
Decisión: Si ves timeouts/reinicios de almacenamiento, estás en territorio de firmware/controlador. Si journald es enorme y crece rápido, limita servicios ruidosos y fija retención sensata.
Task 9: Inspeccionar el ring buffer del kernel por errores de almacenamiento y red
cr0x@server:~$ dmesg -T | egrep -i "nvme|reset|timeout|error|ext4|xfs|zfs|link is down|iommu" | tail -n 25
[Mon Dec 29 09:12:41 2025] nvme nvme0: I/O 123 QID 7 timeout, aborting
[Mon Dec 29 09:12:43 2025] nvme nvme0: Controller reset, clearing queue
[Mon Dec 29 09:12:44 2025] EXT4-fs (nvme0n1p2): warning: mounting fs with errors, running e2fsck is recommended
[Mon Dec 29 09:13:02 2025] igb 0000:03:00.0 eno1: Link is Down
Significado: Timeouts y reinicios no son “ruido”. Son asesinos de rendimiento porque disparan reintentos, flush de colas y bloqueos de aplicaciones. Las advertencias del sistema de archivos pueden provocar trabajo adicional de journaling.
Decisión: Errores de almacenamiento: deja de tunear y empieza a estabilizar (firmware, cableado, BIOS, regresión del kernel). Flaps de enlace de red: revisa driver/firmware de la NIC y el switchport.
Task 10: Validar frecuencia de CPU y governor (la ralentización silenciosa)
cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
powersave
cr0x@server:~$ grep -E "model name|cpu MHz" /proc/cpuinfo | head -n 6
model name : Intel(R) Xeon(R) Silver 4314 CPU @ 2.40GHz
cpu MHz : 800.028
model name : Intel(R) Xeon(R) Silver 4314 CPU @ 2.40GHz
cpu MHz : 800.031
Significado: Si estás clavado en ~800 MHz bajo carga, no “tienes un mal día”, estás limitado por energía. Las actualizaciones pueden cambiar el comportamiento del demonio de perfiles de energía en algunas configuraciones o exponer restricciones del BIOS.
Decisión: En servidores, normalmente quieres rendimiento predecible: establece el governor apropiado (a menudo performance) o usa un perfil tuned que coincida con tus SLO.
Task 11: Ver si la presión de memoria es real (reclaim, swap y riesgos de OOM)
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 62Gi 49Gi 1.2Gi 1.1Gi 12Gi 6.8Gi
Swap: 8.0Gi 2.4Gi 5.6Gi
cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.25 avg60=0.18 avg300=0.12 total=92841712
full avg10=0.03 avg60=0.01 avg300=0.01 total=3812233
Significado: “Available” baja más swap usado puede estar bien para algunas cargas, pero PSI (/proc/pressure) te dice si tareas esperan por memoria. full pressure > 0 sugiere contención seria.
Decisión: Si PSI de memoria sube durante incidentes, ajusta uso de memoria, limita servicios desbocados o añade RAM. Si el swap está thrashing, reduce swappiness o arregla la carga.
Task 12: Buscar límites de cgroup o cambios en contenedores tras actualizaciones
cr0x@server:~$ systemctl status docker --no-pager | sed -n '1,12p'
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2025-12-29 02:16:12 UTC; 7h ago
cr0x@server:~$ cat /sys/fs/cgroup/cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misc
Significado: Ubuntu 24.04 usa cgroup v2 por defecto en configuraciones comunes. Las actualizaciones a veces cambian supuestos del runtime de contenedores. Una aplicación puede quedar limitada por CPU o I/O por política de cgroup, lo que parece “el host está bien pero la app es lenta”.
Decisión: Si ejecutas contenedores, verifica restricciones de recursos y versiones del runtime. Arregla el límite en lugar de tunear ciegamente el host.
Task 13: Comprobar opciones de montaje y salud del sistema de archivos (especialmente tras cambios de kernel)
cr0x@server:~$ findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /
/dev/nvme0n1p2 / ext4 rw,relatime,errors=remount-ro
cr0x@server:~$ sudo tune2fs -l /dev/nvme0n1p2 | egrep -i "Filesystem state|Errors behavior|Default mount options"
Filesystem state: clean
Errors behavior: Remount read-only
Default mount options: user_xattr acl
Significado: Confirmas en qué sistema de archivos estás y cómo está montado. Si se detectaron errores, ext4 puede hacer trabajo extra o remontarse en modo solo lectura.
Decisión: Si el sistema de archivos reporta errores o el kernel registró advertencias, programa una ventana de mantenimiento para fsck e investiga la estabilidad del almacenamiento. No “optimices” un disco roto.
Task 14: Comprobar rápidamente la ruta de red (porque la latencia puede parecer problemas de CPU)
cr0x@server:~$ ip -s link show eno1 | sed -n '1,12p'
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
918273645 821933 12 98 0 1203
TX: bytes packets errors dropped carrier collsns
827364554 801102 0 0 7 0
cr0x@server:~$ ss -s
Total: 1048 (kernel 0)
TCP: 812 (estab 621, closed 134, orphaned 0, synrecv 0, timewait 134/0), ports 0
Transport Total IP IPv6
RAW 0 0 0
UDP 18 12 6
Significado: Errores RX/TX y carrier pueden arrastrar el rendimiento o crear tormentas de reintentos. ss -s da una vista rápida del estado de sockets.
Decisión: Si los errores aumentaron tras una actualización, sospecha del driver/firmware o cambios en ajustes de offload. Valídalo con contadores del switch y considera pinnear/revertir el driver de la NIC si es necesario.
Datos interesantes y contexto (por qué sigue pasando)
- Las actualizaciones de kernel cambian más que “el kernel”. Incluyen nuevos controladores de dispositivos, ajustes del scheduler, comportamiento de la capa de bloques y a veces nuevos valores por defecto. Las rutas de almacenamiento y NIC son especialmente sensibles.
- Los schedulers de I/O en Linux han evolucionado mucho. Los kernels modernos suelen usar por defecto
mq-deadlineononepara NVMe; las guías antiguas que recomiendan CFQ son artefactos históricos de otra era. - La gestión de energía NVMe tiene larga historia de sorpresas. Funciones como APST pueden ser excelentes para energía, pero quirks de firmware pueden causar picos de latencia o reinicios en hardware específico.
- systemd ha absorbido responsabilidades antes manejadas por daemons separados. Eso trae coherencia, pero significa que cambios en systemd/journald pueden aparecer como cambios de comportamiento de rendimiento tras actualizaciones.
- “iowait” no mide la velocidad del disco. Es tiempo de CPU esperando la finalización de E/S. Es un síntoma de que algo bloquea, no la causa raíz por sí solo.
- cgroup v2 es ahora el predeterminado en muchas distribuciones. Mejora el control de recursos, pero las actualizaciones pueden exponer throttling oculto o límites mal configurados, especialmente en entornos containerizados.
- El modelo transaccional de Snap intercambia algo de E/S por confiabilidad. Es una decisión de diseño deliberada: más metadatos y más escritura durante actualizaciones, a menudo notable en discos ocupados o pequeños.
- Los sistemas de archivos con journaling priorizan la consistencia. ext4 y XFS están diseñados para sobrevivir crashes, pero ciertas cargas junto con logging intenso pueden hacer visible el comportamiento de commits del journal como latencia.
- Los microcode updates pueden cambiar características de rendimiento. Corrigen problemas reales de seguridad y estabilidad, pero también pueden alterar comportamiento de boost o mitigar erratas CPU de formas que afectan la latencia cola larga.
Tres microhistorias corporativas desde las trincheras
Microhistoria 1: El incidente causado por una suposición equivocada
La empresa estaba en plena migración a Ubuntu 24.04 y la primera ola se veía bien. Luego, un clúster de nodos “idénticos” empezó a hacer timeouts con carga moderada justo después de la ventana de parches programada. El equipo asumió que era el lanzamiento de la aplicación—porque los lanzamientos de aplicaciones siempre son culpables hasta que se demuestre lo contrario. Iniciaron rollback. Nada mejoró.
Las gráficas mostraron que los hosts no estaban saturados de CPU. La memoria estaba cómoda. Pero la latencia de cola larga estaba destrozada. Los logs estaban llenos de advertencias que nadie tenía tiempo para leer. Entonces hicieron lo que hacen los equipos bajo estrés: añadieron más réplicas. Eso lo empeoró, porque el sistema se volvió más paralelo en E/S y empujó el dispositivo de almacenamiento a colas más profundas.
La suposición equivocada fue sutil: “Todos los discos NVMe se comportan igual.” Esos nodos tenían un modelo NVMe diferente por sustituciones de la cadena de suministro. El nuevo kernel activó una ruta de gestión de energía que el kernel anterior no tocaba. Bajo ciertos patrones de acceso, el firmware del disco reiniciaba el controlador. Cada reinicio causaba segundos de E/S bloqueada, y cada E/S bloqueada se convertía en timeouts de aplicación.
La solución no fue heroica. Pusieron un kernel conocido bueno para esa cohorte de hardware, deshabilitaron la opción de ahorro de energía problemática de NVMe y programaron una validación de firmware. La lección fue dolorosamente simple: variación de hardware más cambio de kernel equivale a “mira el dmesg antes de tocar la app”.
Microhistoria 2: La optimización que salió mal
Otro equipo vio picos de escrituras de disco tras actualizar una flota. Notaron que journald había crecido y decidieron “optimizar” poniendo el journal en el dispositivo más rápido e incrementar la retención “para poder depurar mejor”. Sonó razonable y hasta recibió un visto bueno en chat.
En una semana, el dispositivo más rápido era el más ocupado. Su base de datos compartía ese mismo NVMe. Durante horas punta, la latencia subió y las consultas p99 se pusieron feas. La base de datos no se estaba quedando sin throughput; estaba perdiendo la lotería de latencia porque el logging se había convertido en un escritor constante con puntos de sync.
El fallo no fue journald en sí—fue la combinación de mayor volumen de logs por un servicio nuevo verboso más retención más colocación junto a almacenamiento sensible a latencia. Habían optimizado por “localidad de I/O” y obtuvieron “contención de I/O”.
La solución final fue aburrida: limitar el tamaño del journal, reducir la verbosidad del servicio ruidoso y mover logs de alto volumen fuera del host de forma asíncrona. También separaron “rápido” de “crítico”. El almacenamiento rápido no es sumidero infinito; es donde pones la carga que no puede tolerar encolamiento.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Una organización tenía una regla: cada ventana de parches producía un “registro de cambio” con tres artefactos—versión de kernel, los 20 paquetes principales cambiados y un snapshot de 10 minutos de contadores de rendimiento baseline (CPU, PSI de memoria, latencia iostat y errores de red). No era glamoroso. Nadie se promocionó por ello. Pero hizo los incidentes cortos.
Tras una actualización, un conjunto de servidores API se volvió más lento. El on-call sacó el baseline previo de la última ventana de parches y vio inmediatamente un patrón nuevo: la frecuencia de CPU era menor bajo carga y el cambio de contexto era mayor. La latencia del disco no había cambiado, la red estaba limpia. La clase de cuello de botella era comportamiento de CPU, no almacenamiento.
La causa raíz fue un cambio de perfil de energía tras una actualización de paquete no relacionada. No perdieron horas culpando al kernel o persiguiendo E/S fantasma. Restauraron el perfil de rendimiento, verificaron el escalado de frecuencia bajo carga y cerraron el incidente antes de que el negocio lo escalara.
Esta es la práctica que suena a papeleo hasta que te salva: captura un baseline con el sistema sano. Si no, estás discutiendo con tu propia memoria, que no es una herramienta de monitorización confiable.
Errores comunes: síntoma → causa raíz → solución
Estos son los patrones que veo repetidamente tras actualizaciones de Ubuntu, incluida la 24.04. Los síntomas son lo que la gente reporta. La causa raíz es lo que está pasando realmente. La solución es específica y comprobable.
1) “La carga es alta pero el uso de CPU es bajo”
- Síntoma: El promedio de carga sube;
topmuestra CPUs mayormente inactivas; las apps se detienen. - Causa raíz: Hilos bloqueados en sleep de E/S ininterrumpible (latencia de almacenamiento o reinicios de controlador).
- Solución: Ejecuta
iostat -xzydmesg -T. Si ves timeouts/reinicios NVMe, estabiliza firmware/ajustes del kernel; si la latencia es real, encuentra al escritor coniotop.
2) “Todo es más lento después del reinicio, pero luego mejora gradualmente”
- Síntoma: La primera hora tras reiniciar es terrible; más tarde es tolerable.
- Causa raíz: Tareas post-actualización: seeding/refresh de snap, reconstrucción de caches, updatedb, generación de paquetes de idioma, escaneo de imágenes de contenedores.
- Solución: Usa
systemd-analyze blame,journalctlyiotoppara identificar churn. Reprograma tareas o límitalas. No hagas benchmarks durante el “primer arranque tras la actualización”.
3) “El throughput de disco parece bien, pero la app hace timeout”
- Síntoma: MB/s es alto; los paneles muestran throughput sano; la latencia p99 explota.
- Causa raíz: Latencia y encolamiento, no throughput. Lecturas/escrituras mixtas más logging con sync pueden causar colas y latencias cola larga.
- Solución: Enfócate en
await,aqu-szy E/S por proceso. Reduce frecuencia de sync, separa escritores ruidosos y valida opciones de montaje del sistema de archivos.
4) “La CPU está solo al 30% pero las peticiones son lentas”
- Síntoma: Hay margen; aun así va lento.
- Causa raíz: CPU clavada a baja frecuencia (governor/perfil de energía) o throttling vía límites de cgroup.
- Solución: Comprueba
scaling_governory CPU MHz; verifica límites de contenedores; corrige perfil de energía o política de cgroup.
5) “Tras la actualización, el disco está constantemente ocupado haciendo ‘nada’”
- Síntoma: Alta utilización de disco en reposo; los ventiladores giran; el shell interactivo se siente lento.
- Causa raíz: Crecimiento de journald, tormentas de logs, refresh de snap o un scanner/indexador habilitado recientemente.
- Solución: Identifica al escritor con
iotop. Limita la fuente ruidosa, acota el tamaño del journal y gestiona ventanas de refresh de snap.
6) “La red se volvió inestable y ahora el rendimiento es terrible”
- Síntoma: Reintentos, llamadas API lentas, timeouts intermitentes.
- Causa raíz: Regresión de driver, cambio en ajustes de offload, flaps de enlace o desajuste de MTU tras la actualización.
- Solución: Inspecciona
ip -s linkerrores y mensajes de enlace endmesg; coordina con contadores de red; ajusta offloads solo con evidencia.
Broma #2: Las regresiones de kernel son como las máquinas de café de la oficina: en el momento en que dependes de ellas, desarrollan “carácter”.
Listas de verificación / plan paso a paso
Checklist A: Triage de 10 minutos en un host
- Registra kernel y uptime (
uname -a,uptime -s). - Revisa actualizaciones recientes (
/var/log/dpkg.logtail). - Revisa servicios fallidos y blame del arranque (
systemctl --failed,systemd-analyze blame). - Clasifica con
vmstat 1(observawa,si,so). - Mide latencia de disco con
iostat -xz. - Atribuye E/S con
iotop -oPasi el disco está caliente. - Revisa logs del kernel por timeouts/reinicios (
dmesg -Tfiltrado). - Comprueba governor y frecuencia de CPU (
scaling_governor,/proc/cpuinfo). - Revisa PSI de memoria (
/proc/pressure/memory) y uso de swap (free -h). - Toma una decisión: mitigar (parar al culpable), revertir kernel o abrir investigación de hardware/controlador.
Checklist B: Cuando es un problema de flota (no un solo host)
- Elige tres hosts: uno rápido, uno lento, uno promedio.
- Compara versiones de kernel y paquetes de microcode.
- Compara IDs de hardware (modelo NVMe, modelo NIC) para no perseguir “software” que en realidad es variación de hardware.
- Compara latencia de
iostaty errores dedmesgentre cohortes. - Si se correlaciona con un build de kernel específico, considera pinnear o revertir ese kernel en hardware afectado.
- Confirma si nuevos servicios están habilitados en hosts lentos (
systemctl list-unit-files --state=enableddiff).
Checklist C: Acciones de mitigación controladas (haz esto, no tunear al azar)
- Si el disco está saturado por logs: reduce la verbosidad, limita el tamaño del journal, mueve logs de alto volumen fuera del host asíncronamente.
- Si el refresh de snap interfiere con SLOs: programa ventanas de refresh y evita el seeding durante picos.
- Si aparecen reinicios NVMe: prioriza validar firmware y mitigaciones por parámetros del kernel por sobre “tunear el sistema de archivos”.
- Si la frecuencia de CPU está atascada: corrige governor/perfil y confirma bajo carga con pruebas repetibles.
- Si la PSI de memoria es alta: reduce el working set, corrige fugas, aplica límites o añade RAM—luego vuelve a medir.
Preguntas frecuentes
1) ¿Cómo sé si la ralentización es CPU, disco o memoria?
Usa vmstat 1 y iostat -xz. wa alto + await alto indica latencia de disco. Actividad de swap y PSI de memoria apuntan a presión de memoria. CPU user/system alto con bajo iowait apunta a CPU o overhead de syscalls.
2) La actualización terminó, pero no reinicié. ¿Puede cambiar el rendimiento igual?
Sí. Servicios de userspace pueden reiniciarse, la configuración puede cambiar y tareas en segundo plano (refresh de snap, reconstrucción de caches) pueden ejecutarse de inmediato. El comportamiento de kernel/controlador suele cambiar tras reiniciar, pero no todas las regresiones requieren reinicio.
3) ¿Por qué importa tanto iowait si la CPU parece inactiva?
Porque tus hilos de aplicación esperan por almacenamiento. CPUs inactivas no ayudan si la ruta de la petición está bloqueada en fsync, escrituras de metadata o reintentos de dispositivo. Mide latencia de disco, no solo utilización.
4) ¿Debería revertir el kernel inmediatamente?
Si tienes evidencia clara de reinicios/timeouts de controladores o una regresión correlacionada por cohortes con un kernel específico, revertir es una contención razonable. Si el cuello de botella es un servicio ruidoso o logging, revertir no ayudará y será una pérdida de tiempo.
5) Snapd está ocupado tras la actualización—¿elimino snaps?
No como reacción instintiva. Primero confirma que snapd es el culpable con iotop y systemd-analyze blame. Luego controla ventanas de refresh y reduce conflictos con cargas sensibles a latencia. Eliminar snaps puede crear más superficie operativa de la que ahorras.
6) ¿Cuál es la forma más rápida de detectar problemas NVMe?
dmesg -T filtrado por nvme, timeout y reset, más iostat -xz para picos de latencia. Si ves reinicios de controlador, deja de tunear el sistema de archivos y valida firmware y comportamiento del kernel.
7) ¿Cómo aparecen las denegaciones de AppArmor como “problemas de rendimiento”?
Las denegaciones pueden forzar retrocesos, fallos repetidos o reintentos en rutas calientes. Revisa journalctl por mensajes de AppArmor y correlaciona timestamps con latencia. La solución suele ser ajustar la política o corregir rutas de archivos esperadas por el servicio—no deshabilitar AppArmor en general.
8) ¿Es seguro poner el governor en performance en servidores Ubuntu 24.04?
A menudo sí para producción sensible a latencia, asumiendo que potencia y térmicos están dimensionados correctamente. Pero trátalo como un cambio: aplícalo a un subconjunto, mide y confirma que no desencadenas throttling térmico ni violas presupuestos de energía.
9) ¿Por qué journald a veces se convierte en un cuello de botella?
El logging de alto volumen son escrituras pequeñas sostenidas más actualizaciones de metadata. Si un servicio se vuelve ruidoso tras una actualización, journald puede generar presión constante de escritura y puntos de sync. Limita tamaño, reduce verbosidad y evita colocar churn de logs junto a tu almacenamiento más sensible si puedes.
Pasos prácticos siguientes
Haz esto hoy, mientras el incidente aún está fresco y la evidencia no se ha perdido en los logs:
- Ejecuta el plan rápido de diagnóstico en un host afectado y en uno no afectado. Anota: kernel, latencia iostat, proceso principal de I/O y cualquier error en dmesg.
- Si ves timeouts/reinicios de dispositivo: contiene el radio de impacto (pinea/revierte kernel en la cohorte de hardware afectada) y abre investigación de firmware/controlador.
- Si ves churn de I/O por logs o snap: limítalo, prográmalo o muévelo. No permitas que mantenimiento en segundo plano compita con los SLOs de primer plano.
- Si la frecuencia de CPU está mal: corrige governor/perfil y verifica bajo carga con mediciones repetibles, no con sensaciones.
- Captura un artefacto baseline después de estabilizar. En la próxima ventana de parches te lo agradecerás.