Vista rápida con top
top Pulsa P para ordenar por CPU y M por memoria. Observa load average, porcentaje idle, wa de espera de disco y memoria available. Un instante no basta: mira varios intervalos.
Listar procesos con ps
ps aux --sort=-%cpu | head -20
ps aux --sort=-%mem | head -20 RSS aproxima memoria física residente. %MEM facilita comparar, pero procesos relacionados pueden compartir páginas.
Medir durante un periodo
sudo apt install -y sysstat
pidstat -u -r -d 1 pidstat relaciona CPU, memoria y E/S por proceso. iostat -xz 1 ayuda a confirmar espera de almacenamiento; vmstat 1 muestra cola, swap y CPU del sistema.
Servicios y contenedores
systemd-cgtop
docker stats --no-stream Estos comandos agrupan mejor que una lista de procesos cuando una aplicación tiene muchos workers.
Interpretar load average
Una carga de 4 puede saturar un VPS de 2 vCPU y ser normal en uno de 16. La carga también incluye tareas esperando E/S. Si CPU idle es alta pero wa también, investiga almacenamiento en lugar de comprar más CPU.
Interpretar RAM
Linux usa RAM para caché. free -h muestra available, una estimación de lo que puede entregarse sin empezar a intercambiar agresivamente. Revisa OOM y swap antes de concluir que la caché es un problema.
Crear una línea base
Guarda métricas históricas de CPU, RAM, disco, tráfico y latencia. Sin una línea base solo sabes cómo está ahora, no qué cambió. Correlaciona el pico con despliegues, cron, backups y tráfico.
Si confirmas falta de memoria, sigue VPS sin RAM. Si el disco espera, compara NVMe y SSD sin olvidar consultas y límites.
Empezar por el síntoma que percibe el usuario
La investigación debe relacionar consumo con una degradación concreta: latencia, errores, cola o proceso terminado. Un servidor puede usar 90 % de CPU durante una tarea programada y seguir cumpliendo; otro puede mostrar 30 % total mientras un único hilo bloquea la ruta crítica.
Antes de cambiar nada, anota hora, URL o servicio afectado y duración. Después captura una vista general:
date -Is
uptime
free -h
vmstat 1 5
df -h
sudo ss -s uptime muestra la carga, free resume memoria, vmstat permite ver si cambia durante varios segundos, y df descarta un disco lleno que puede parecer un problema de CPU. Guardar la hora permite cruzar la observación con logs de aplicación, proxy y kernel.
No reinicies inmediatamente. Un reinicio puede bajar el consumo y borrar el estado que permitía identificar una fuga, una consulta atascada o un job duplicado.
Leer correctamente la línea de CPU en top
Los porcentajes de CPU explican dónde pasó el tiempo el procesador, no solo cuánto estuvo ocupado. En top, los campos más útiles son:
-
us: código de aplicaciones en espacio de usuario. -
sy: trabajo del kernel, red, sistema de archivos y llamadas del sistema. -
id: tiempo ocioso. -
wa: tiempo esperando E/S. -
st: tiempo que el hipervisor no entregó a la máquina virtual.
Pulsa 1 para separar CPU lógicas. Si una aparece al 100 % y las demás libres, probablemente existe una tarea de un solo hilo; añadir más núcleos no acelera ese proceso salvo que la aplicación pueda paralelizarse.
Ejecuta una captura no interactiva que puedas adjuntar a un incidente:
top -b -n 3 -d 2 | tail -80 No concluyas que el disco es lento solo por un pico de wa. Correlaciónalo con iostat y con la latencia de dispositivos. Del mismo modo, st sostenido puede indicar contención del host virtual, pero primero descarta límites de CPU aplicados a tu VPS o contenedor.
Ordenar procesos sin perder el contexto
ps responde quién acumula recursos en ese instante, mientras pidstat muestra cómo cambia cada proceso. Amplía la salida para incluir identificador, padre, tiempo y comando:
ps -eo pid,ppid,user,%cpu,%mem,rss,etime,stat,comm,args \
--sort=-%cpu | head -25
ps -eo pid,ppid,user,%cpu,%mem,rss,etime,stat,comm,args \
--sort=-rss | head -25 Un proceso hijo puede aparecer como responsable aunque el servicio que lo crea sea otro. Sigue el PPID o muestra el árbol:
pstree -aps PID
systemctl status NOMBRE_SERVICIO --no-pager Para una aplicación con workers, observa por proceso durante al menos un minuto:
pidstat -u -r -d -h 2 30 La opción -u mide CPU, -r memoria y fallos de página, y -d E/S. Un proceso que alterna picos breves puede desaparecer en una captura de ps pero queda evidente en la serie.
Encontrar un hilo que satura un núcleo
Un proceso multihilo puede mostrar 100 % o más según la herramienta, pero solo uno de sus hilos estar atascado. Examina los hilos del PID:
top -H -p PID
ps -L -p PID -o pid,tid,psr,pcpu,stat,comm --sort=-pcpu Esto es especialmente útil para runtimes Java, bases de datos y servidores que crean pools. El identificador TID permite relacionar un hilo con trazas de la aplicación. No mates el proceso solo porque un hilo consume CPU: primero determina si realiza trabajo esperado, como compresión, indexación o una consulta legítima.
Si el mismo hilo queda saturado sin completar trabajo, captura un perfil con herramientas propias del runtime durante una ventana breve. Un profiler mal utilizado en producción también añade carga; empieza por logs, métricas y una réplica del problema cuando sea posible.
Interpretar RAM más allá de used y free
La columna available estima cuánta memoria puede entregarse sin recurrir a intercambio agresivo. Revisa el detalle:
free -h
grep -E 'MemTotal|MemAvailable|Cached|Buffers|SwapTotal|SwapFree|Dirty|Writeback' /proc/meminfo La caché de archivos acelera lecturas y se libera bajo presión. Señales más fiables de falta real de memoria son available persistentemente bajo, swap entrando y saliendo, latencia creciente y eventos OOM.
ps muestra RSS, pero sumar RSS de todos los procesos sobreestima cuando comparten bibliotecas. Si necesitas una atribución más precisa instala smem y revisa PSS:
sudo apt install -y smem
sudo smem -tk
sudo smem -r -s pss | head -25 PSS distribuye las páginas compartidas entre procesos. Aun así, la memoria del kernel, cachés y tmpfs no pertenecen de forma simple a una aplicación; por eso el total del sistema y la atribución por proceso deben leerse juntos.
Detectar swap activa y thrashing
Tener swap usada no significa por sí solo que el servidor esté fallando; el problema es el intercambio continuo que aumenta la latencia. Observa si y so en vmstat:
vmstat 1 10
swapon --show Valores sostenidos de entrada y salida, junto con poca memoria disponible, indican presión. Identifica entonces qué servicio creció y si tiene límites razonables. Vaciar swap con swapoff durante presión puede forzar todos los datos a RAM y disparar el OOM; no lo uses como limpieza rutinaria.
Para un servicio que usa memoria de manera creciente, registra RSS a intervalos y relaciónalo con tráfico. Una fuga muestra una tendencia que no vuelve a la línea base después de bajar la carga. Una caché diseñada puede crecer hasta un límite y estabilizarse, lo cual requiere una decisión distinta.
Confirmar eventos del OOM killer
Cuando el kernel no puede satisfacer memoria, puede terminar un proceso y dejar la única explicación en el registro del kernel. Busca el momento exacto:
sudo journalctl -k --since '24 hours ago' \
| grep -Ei 'out of memory|oom-kill|killed process'
sudo dmesg -T | grep -Ei 'out of memory|oom-kill|killed process' Registra PID, nombre, cgroup y consumo indicado. En un contenedor con límite, el OOM puede ocurrir dentro de su cgroup aunque el host tenga memoria libre. Comprueba los límites en Docker o systemd antes de ampliar el VPS.
Después estabiliza con la medida de menor impacto: reducir concurrencia, detener un job no esencial o revertir el despliegue que inició el crecimiento. La corrección permanente puede ser optimizar, limitar una caché, reparar una fuga o aumentar capacidad. Añadir reinicios periódicos oculta el defecto y crea cortes programados.
Saber si el almacenamiento es el cuello de botella
CPU ociosa con procesos lentos suele señalar espera de disco, pero se confirma con latencia y cola. Instala sysstat y mide varios intervalos:
sudo apt install -y sysstat
iostat -xz 1 10 Observa latencias de lectura y escritura, utilización y tamaño de cola en el contexto del dispositivo. Un porcentaje alto de utilización no siempre es malo en NVMe capaces de paralelismo; la latencia que afecta solicitudes es la señal decisiva.
Para identificar procesos que generan E/S:
sudo iotop -oPa
pidstat -d 1 20 Un backup, compresión de logs o checkpoint de base puede competir con el tráfico. Cambiar el horario o limitar E/S puede resolver mejor que comprar CPU. Si la base produce muchas lecturas aleatorias, revisa índices y memoria de caché antes de atribuirlo solo al tipo de disco.
Relacionar load average con núcleos y estados
La carga no es un porcentaje; es una cantidad de tareas ejecutables o esperando de forma no interrumpible. Obtén CPU lógicas y carga juntas:
nproc
cat /proc/loadavg
uptime En 2 vCPU, una carga sostenida cerca de 2 puede significar que ambos están ocupados; una carga de 8 implica cola. En 16 vCPU, carga 4 deja margen. Sin embargo, tareas bloqueadas por E/S también suman, así que revisa estados:
ps -eo state,pid,comm,wchan:32 --sort=state | awk '$1 ~ /D/' El estado D indica espera no interrumpible, común en E/S. Muchos procesos en D con CPU ociosa cambian el foco hacia disco, almacenamiento de red o kernel.
Medir servicios systemd y cgroups
Cuando una aplicación crea muchos procesos, agrupar por servicio evita culpar a un worker aislado. Usa:
systemd-cgtop
systemctl status nginx --no-pager
systemctl show miapp.service \
-p MemoryCurrent -p MemoryPeak -p CPUUsageNSec -p TasksCurrent Los valores disponibles dependen de systemd y del cgroup configurado. Si un servicio necesita protección, puedes aplicar límites en una unidad, pero pruébalos: MemoryMax demasiado ajustado convierte picos legítimos en terminaciones.
[Service]
MemoryHigh=800M
MemoryMax=1G
CPUQuota=150% MemoryHigh introduce presión antes del máximo; MemoryMax es un límite duro. No copies cifras de otro servidor: mide la carga, incluye picos y documenta qué ocurre al llegar al límite.
Analizar contenedores y sus límites
docker stats atribuye consumo al cgroup del contenedor, que es más útil que buscar procesos con nombres repetidos en el host. Captura una foto y examina límites:
docker stats --no-stream
docker inspect NOMBRE_CONTENEDOR \
--format 'memory={{.HostConfig.Memory}} cpus={{.HostConfig.NanoCpus}}'
docker top NOMBRE_CONTENEDOR Un contenedor sin límite puede usar todo el host. Uno con límite bajo puede recibir OOM dentro del cgroup. Cruza su reinicio y código de salida:
docker inspect NOMBRE_CONTENEDOR \
--format 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}} restarts={{.RestartCount}}'
docker logs --since=30m NOMBRE_CONTENEDOR No asumas que 100 % en Docker significa toda la máquina: normalmente representa la capacidad de una CPU lógica. Compara con los núcleos disponibles y con límites definidos.
Guardar histórico para problemas que ya terminaron
Sin métricas históricas, un pico nocturno desaparece antes de que alguien pueda investigarlo. sar del paquete sysstat puede registrar CPU, memoria y carga si su recolección está habilitada.
systemctl status sysstat --no-pager
sar -u
sar -r
sar -q Para revisar un archivo diario concreto, usa la ruta de tu distribución en /var/log/sysstat/. Comprueba que existe información antes de esperar al siguiente incidente.
Una plataforma de monitoreo debe conservar al menos CPU por modo, memoria disponible, swap, latencia de disco, espacio, red, reinicios y latencia de aplicación. Las alertas necesitan duración: avisar por un segundo de CPU alta produce ruido; alertar por cola sostenida con degradación responde a impacto real.
Un flujo de diagnóstico de quince minutos
Cambia de herramienta solo cuando la evidencia lo justifique. Una secuencia reproducible es:
- 1 Registrar hora y síntoma.
- 2 Capturar
uptime,free,vmstaty disco. - 3 Identificar procesos con
psy observarlos conpidstat. - 4 Separar CPU, memoria, E/S y contención virtual.
- 5 Correlacionar con despliegues, cron, backups y tráfico.
- 6 Aplicar una mitigación reversible.
- 7 Repetir la misma prueba del usuario.
Guarda una evidencia compacta:
incident="/tmp/recursos-$(date +%F-%H%M%S).txt"
{
date -Is
uptime
free -h
vmstat 1 5
ps -eo pid,ppid,user,%cpu,%mem,rss,etime,stat,comm --sort=-%cpu | head -25
} | tee "$incident" Este archivo no incluye argumentos completos para reducir el riesgo de capturar secretos. Revísalo antes de compartirlo fuera del equipo.
Elegir la corrección según el patrón
| Evidencia | Corrección inicial | Solución de fondo |
|---|---|---|
| Un hilo al 100 % | Reducir trabajo o revertir cambio | Paralelizar u optimizar el código |
| Muchos workers en cola | Limitar concurrencia | Dimensionar y eliminar el cuello siguiente |
| RAM crece sin volver | Reinicio controlado para estabilizar | Perfilar y corregir fuga |
| OOM en contenedor limitado | Ajustar límite con margen | Medir pico y optimizar proceso |
iowait y latencia altos | Pausar backup o job | Índices, horarios, caché o almacenamiento |
steal sostenido | Documentar con series | Revisar límites o proveedor |
| Disco lleno por logs | Rotar sin borrar evidencia necesaria | Política de retención y alertas |
Comprar un VPS mayor puede ser correcto si la carga legítima supera de forma sostenida la capacidad, pero no repara una consulta sin índice ni un bucle infinito. Mide después del cambio con el mismo tráfico y la misma ruta para demostrar que la causa quedó resuelta.
Correlacionar picos con cron, timers y despliegues
Un consumo periódico suele tener una causa programada: respaldo, rotación, escaneo, reporte o actualización. Revisa cron y timers alrededor de la hora del incidente:
systemctl list-timers --all
sudo journalctl --since 'today 02:00' --until 'today 03:00'
sudo grep -Rni '' /etc/cron.d /etc/cron.daily 2>/dev/null No desactives un backup porque usa disco; quizá la corrección sea moverlo fuera de la hora de tráfico, limitar su E/S o evitar que coincida con otra tarea. Registra también despliegues y cambios de configuración. Si la RAM comenzó a crecer justo después de una versión, revertir aporta evidencia más fuerte que reiniciar la misma.
Mitigar un incidente sin destruir la evidencia
La primera acción debe recuperar servicio con el menor cambio reversible. Si un job no esencial satura CPU, puedes pausar su proceso mientras capturas estado:
sudo kill -STOP PID
sleep 10
sudo kill -CONT PID Detener temporalmente no es solución y puede ser peligroso para bases o procesos que mantienen bloqueos; úsalo solo cuando entiendas el servicio. Para unidades systemd, reducir prioridad de CPU o E/S durante la tarea puede ser más controlable que matarla.
Antes de terminar un proceso, registra comando, árbol, archivos abiertos y logs. Una señal TERM permite salida limpia; KILL no da oportunidad de confirmar transacciones ni vaciar buffers. Escala solo si el proceso no responde y el impacto justifica el riesgo.
Verificar después de optimizar o ampliar el VPS
Una mejora debe reducir el síntoma con carga comparable y no mover el cuello de botella a otra capa. Repite las mismas métricas y una acción del usuario. Si amplías CPU, revisa que base y disco no se conviertan en la nueva cola. Si añades RAM, confirma menos presión y no solo una caché mayor.
Guarda antes y después con hora, versión y tráfico. Un cambio realizado durante una caída natural de visitas puede parecer exitoso aunque no haya corregido nada. Observa al menos otro periodo de carga esperado y conserva alertas de recurrencia.
La capacidad correcta incluye margen para picos, actualizaciones y backups, pero no debe financiar indefinidamente una fuga. Si el proceso crece sin límite, perfilar y corregir sigue siendo necesario incluso después de escalar.
Distinguir carga legítima de un proceso comprometido
Un minero o proceso no autorizado puede parecer simplemente una aplicación con CPU alta. Revisa usuario, ejecutable, padre, conexiones y fecha de inicio antes de asumir que pertenece al servicio:
readlink -f /proc/PID/exe
ps -p PID -o pid,ppid,user,lstart,etime,args
sudo lsof -Pan -p PID -i
sudo ls -l /proc/PID/exe /proc/PID/cwd No ejecutes binarios desconocidos ni los borres antes de conservar evidencia si existe un incidente de seguridad. Aísla red cuando el riesgo lo justifique, rota credenciales desde un equipo limpio y revisa persistencia en systemd, cron, usuarios y llaves SSH.
Un nombre parecido a un proceso del sistema no lo legitima. Compara la ruta con el paquete instalado y su firma o hash mediante herramientas de la distribución. Si confirmas compromiso, reconstruir desde una imagen confiable suele ofrecer más garantías que matar un PID y continuar.
Investigar CPU del kernel, interrupciones y red
Un valor alto en sy indica trabajo del kernel, que puede provenir de red, almacenamiento, firewall o muchas llamadas cortas. No aparecerá siempre como un proceso de usuario claramente dominante. Revisa interrupciones y softirqs:
mpstat -P ALL 1 10
mpstat -I SUM 1 10
cat /proc/softirqs Mucho tráfico, paquetes pequeños o reglas complejas pueden consumir CPU en procesamiento de red. Observa interfaces y errores:
ip -s link
sar -n DEV 1 10
sudo ss -s Si una interfaz recibe un pico inesperado, correlaciona con logs del proxy y firewall. No bloquees direcciones por una única captura: CDN, monitoreo y clientes legítimos pueden compartir rangos. Aplica mitigación aguas arriba si el enlace se satura.
Un número elevado de cambios de contexto o interrupciones también puede provenir de demasiados workers. vmstat muestra in y cs; compáralos con tu línea base. Reducir procesos puede mejorar más que añadir CPU cuando la coordinación consume el tiempo disponible.
Compartir diagnósticos sin exponer credenciales
Las líneas de comandos pueden contener tokens, contraseñas, URLs privadas o datos de clientes. ps aux y un volcado de entorno no deben copiarse íntegros a un ticket público. Recorta argumentos sensibles y conserva la evidencia original con acceso restringido.
Prioriza PID, usuario, consumo, tiempo y nombre del ejecutable. Cuando necesites argumentos completos, revisa antes de exportar:
ps -eo pid,user,%cpu,%mem,rss,etime,comm --sort=-%cpu | head -30 Los perfiles de memoria y volcados de proceso pueden contener contenido de solicitudes. Obtén autorización y define retención. La observabilidad debe ayudar a reparar el servicio sin crear una segunda fuga más grave que el pico investigado.
Empieza con top y ps, confirma con pidstat, vmstat e iostat y agrupa por servicio o contenedor. Mide durante el problema y conserva histórico: el nombre del proceso y el patrón temporal conducen a la solución.
Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.