El swap de Proxmox sigue creciendo: qué falla con la presión de memoria y cómo estabilizarlo

¿Te fue útil?

Tu host Proxmox tiene “montones de RAM libre”, pero el uso de swap sube como si estuviera entrenando para un maratón. Las VM se sienten lentas. La carga del nodo sube.
Y cada reboot “lo arregla” por un rato, que es el tipo de arreglo que pertenece a una casa encantada, no a un centro de datos.

El crecimiento de swap en un hypervisor rara vez es misterioso. Normalmente es una de tres cosas: en realidad estás bajo presión de memoria, has configurado el host
de modo que el reclaim se comporta mal, o estás leyendo la métrica equivocada y persiguiendo fantasmas. Volvamos a hacerlo aburrido.

Guía rápida de diagnóstico

Si sólo tienes 10 minutos antes de que alguien sugiera “simplemente añade RAM”, haz esto en orden. Estás intentando responder una pregunta:
¿el crecimiento de swap está causado por presión real, reclaim defectuoso o por un panel que miente?

1) Confirma que el síntoma es real (y no sólo pánico por “memoria cached”)

  • Comprueba el swap usado en el host y la tasa de I/O de swap (no sólo “swap usado”).
  • Comprueba la presión de memoria (PSI) y la actividad de kswapd.

2) Identifica la fuente de la presión

  • ¿Está ZFS ARC consumiendo el margen?
  • ¿Estás sobredimensionando la RAM entre VMs o contenedores?
  • ¿El ballooning está forzando a los invitados a bajar y empujando al host a un caos de reclaim?

3) Decide el estabilizador

  • Si la presión es sostenida: reduce compromisos (memoria de VM), limita ARC o añade RAM.
  • Si el reclaim es patológico: corrige swappiness, watermark y las interacciones con hugepages/THP; añade zram si procede.
  • Si el swap está “usado pero silencioso”: considera dejarlo, o vaciar el swap lentamente sin provocar tormentas.

Regla operativa: swap usado sin I/O de swap puede estar bien. Swap usado con alto swap-in/swap-out es donde el rendimiento muere.

El crecimiento de swap no es automáticamente un fallo

Linux moverá oportunistamente páginas anónimas frías al swap para mantener más RAM disponible para page cache y metadatos del sistema de ficheros. En un equipo de escritorio,
esto puede ser una ventaja. En un hypervisor, depende. Tus páginas “frías” pueden pertenecer a procesos qemu que de repente las necesiten. Ahí es cuando ves
una VM congelarse por un segundo y tus usuarios inventan nuevos adjetivos.

Una distinción clave:

  • Ocupación de swap: cuánto swap está usado ahora mismo.
  • Actividad de swap: cuánta data se mueve dentro/fuera del swap por segundo.

La ocupación de swap puede crecer y mantenerse alta durante meses si el kernel swapó páginas frías y nunca las volvió a necesitar. Eso no es un incendio.
La actividad de swap durante horas laborales es un incendio. Un incendio silencioso, pero incendio al fin.

Broma #1: Swap es como un trastero. Puedes dejar cosas durante años, pero el momento en que necesitas algo durante una reunión, lo lamentarás.

Hechos interesantes y contexto histórico

  1. Antes Linux mostraba “memoria libre” como titular, y la gente afinó sistemas por años; la guía moderna enfatiza la memoria “available”.
  2. Swappiness no es “agresividad de swap” de forma simple; influye en el balance de reclaim entre páginas anónimas y cache de archivos, y su comportamiento cambia según la era del kernel.
  3. El OOM killer no es un bug; es Linux eligiendo “un proceso debe morir para que el sistema viva”, lo cual suele ser correcto en un host pero doloroso en virtualización.
  4. ZFS ARC está diseñado para consumir RAM porque el cache mejora el rendimiento; sin un límite puede expulsar a los invitados en un hypervisor.
  5. Pressure Stall Information (PSI) llegó para cuantificar el “tiempo detenido” bajo presión—finalmente convirtiendo “se siente lento” en una señal mensurable.
  6. Los memory cgroups cambiaron las reglas al habilitar contabilidad y comportamiento de reclaim por VM/contenedor—a veces mejorando el aislamiento, otras añadiendo sorpresas.
  7. KSM (Kernel Samepage Merging) fue importante para densidad en virtualización, pero intercambia CPU por RAM y puede interactuar con reclaim de forma inesperada.
  8. Transparent Huge Pages se introdujeron para rendimiento, pero en virtualización pueden aumentar picos de latencia durante compaction y reclaim.
  9. Los valores por defecto y heurísticos de swappiness evolucionaron porque los SSD hicieron el swap menos catastrófico que en discos giratorios—sin embargo I/O aleatorio de swap sigue castigando cargas sensibles a la latencia.

Cómo decide Linux reclamar memoria (y por qué Proxmox lo complica)

Proxmox es “solo Debian”, pero en producción nunca es “solo”. Estás ejecutando procesos qemu-kvm (grandes consumidores de memoria anónima), posiblemente contenedores LXC,
y tal vez ZFS, que es un sistema de ficheros de alto rendimiento feliz de usar mucha RAM. Luego añades ballooning, que es básicamente una mentira negociada:
“sí invitado, todavía tienes 16 GB”, mientras el host silenciosamente te los pide de vuelta.

Tres categorías importan: anónimas, cache de archivos y reclamabilidad

Cuando la RAM se aprieta, el kernel reclama memoria principalmente mediante:

  • Descartar la cache de archivos (fácil y rápido si el cache se puede desechar).
  • Escribir páginas sucias a disco (puede ser lento; depende del almacenamiento).
  • Swap de memoria anónima (páginas de proceso no respaldadas por un fichero).

La virtualización convierte la RAM del invitado en páginas anónimas del host. Eso significa que el mayor consumidor de RAM del hypervisor es precisamente el tipo de memoria que Linux
está dispuesto a swapear si piensa que puede mantener el sistema responsive. Y ya sabes cómo termina eso.

La presión de memoria no es “poca memoria libre”

Linux usa con gusto RAM para cache; no está desperdiciada. La métrica que quieres es MemAvailable (desde /proc/meminfo) y, mejor, las señales PSI
que muestran si las tareas se quedan bloqueadas esperando reclaim de memoria.

ZFS complica el reclaim

ZFS ARC es técnicamente reclaimable, pero no es “page cache” del mismo modo que el cache de ext4. ARC compite con las VMs por memoria. Si ARC crece sin límite,
el host puede empezar a swapear páginas de invitados mientras mantiene mucho cache de ZFS. Esa es una compensación que rara vez quieres en un hypervisor:
la latencia de I/O de swap es peor que un ARC más pequeño.

El ballooning puede crear “margen falso”

El ballooning está bien cuando se usa intencionalmente (para elasticidad, no para denegación). Pero si sobredimensionas y dependes del ballooning como red de seguridad,
puedes empujar a los invitados a su propio reclaim mientras el host también reclama. Dos capas de reclaim. Doble diversión. Mitad de estabilidad.

Cita (idea parafraseada): “La esperanza no es una estrategia” — atribuida comúnmente a líderes de operaciones; trátala como principio, no como cita literal.

Qué suele causar “el swap sigue creciendo” en Proxmox

1) Sobredimensión real: asignaste más memoria de la que posees

Este es el clásico. Sumas la “memoria asignada” de las VM y supera la RAM física por mucho, luego te sorprendes cuando el host usa swap.
El host no está equivocado. Tu hoja de cálculo sí.

2) ZFS ARC crece y ocupa el margen de las VMs

En una máquina de almacenamiento dedicada, dejar que ARC use la mayor parte de la memoria es genial. En un hypervisor, ARC necesita límites. Si no, ARC se vuelve “ese inquilino”
que ocupa toda la cocina y se ofende si le pides que comparta.

3) Swappiness y tunning de reclaim desajustados para un hypervisor

Los valores por defecto son razonables para un Linux general. Los hypervisors no son generales. La combinación equivocada puede llevar a swapear páginas qemu temprano incluso cuando
descartar cache habría sido más barato.

4) Fragmentación de memoria / problemas de compactación (THP y hugepages)

Si el host lucha para asignar memoria contigua, la compactación y el reclaim se vuelven ruidosos. Esto puede parecer “el swap sigue creciendo”, pero la causa raíz
es latencia y CPU consumida en las rutas de reclaim.

5) Algo filtra, pero no donde piensas

A veces es una fuga real: un agente de monitorización, un proceso de backup, o un contenedor desbocado. Pero más a menudo es “crecimiento constante” causado por cache
(ZFS ARC, slab caches) que parece una fuga en el panel equivocado.

6) Almacenamiento lento hace que el swap sea “pegajoso”

Si tu dispositivo de swap es lento o está saturado, las páginas swapadas no vuelven rápido. El kernel puede mantenerlas en swap por más tiempo, haciendo que el uso de swap suba
y se mantenga alto. No porque el kernel ame el swap—porque tus discos te odian.

Broma #2: El kernel no “swapea al azar”. Swapea con la calma y certeza de quien sabe que no planificaste capacidad y quiere que aprendas.

Tareas prácticas: comandos, salidas, decisiones

A continuación hay tareas listas para campo. Cada una tiene: un comando, qué significa la salida y la decisión que tomas. Ejecútalas en el host Proxmox primero.
Luego, cuando sea necesario, dentro de un invitado con mal comportamiento.

Task 1: Confirma la ocupación de swap y los dispositivos de swap

cr0x@server:~$ swapon --show --bytes
NAME       TYPE SIZE        USED       PRIO
/dev/sda3  part 17179869184 4294967296  -2

Significado: Tienes una partición de swap de 16 GiB y 4 GiB están actualmente usados.
Decisión: Si USED es alto, no te desesperes aún—revisa la actividad a continuación. Si el swap está en un disco lento compartido con almacenamiento de VM, considera moverlo.

Task 2: Comprueba la actividad de swap (la métrica real de “¿esto duele?”)

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
 1  0 4194304 812344  53212 921344   0    0    12    30  400  700  3  2 94  1  0
 2  0 4194304 790112  53044 910020   0    0     0    64  420  760  4  3 92  1  0
 3  1 4194304 120312  52880 302120   0  512   120  2000  800 1500 20 10 55 15  0
 2  2 4194816  90344  52000 280000 128 1024   300  5000 1200 2000 25 12 40 23  0
 1  1 4198912  81200  51000 270000 256 2048   500  8000 1500 2500 22 15 35 28  0

Significado: si/so son swap-in/swap-out KB/s. En las últimas muestras son no nulos y en aumento: swapping activo.
Decisión: Swapping activo significa impacto de rendimiento. Pasa al diagnóstico de presión; planifica reducir la presión de memoria o cambiar el comportamiento de reclaim.

Task 3: Comprueba MemAvailable y totales de swap

cr0x@server:~$ grep -E 'MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree' /proc/meminfo
MemTotal:       263989996 kB
MemFree:         1123400 kB
MemAvailable:   34122388 kB
SwapTotal:      16777212 kB
SwapFree:       12582912 kB

Significado: MemFree es pequeño (normal), MemAvailable es ~32 GiB (buen margen).
Decisión: Si MemAvailable está sano pero la actividad de swap es alta, sospecha patologías de reclaim, presión por ZFS ARC o límites por cgroup.

Task 4: Lee la presión de memoria PSI (¿las tareas se quedan bloqueadas?)

cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.15 avg60=0.20 avg300=0.35 total=18203456
full avg10=0.02 avg60=0.04 avg300=0.05 total=3401120

Significado: “some” es tiempo donde al menos una tarea quedó bloqueada por memoria; “full” es tiempo donde todas las tareas ejecutables estaban bloqueadas.
Un “full” no trivial indica bloqueos visibles por el usuario.
Decisión: Si PSI full está elevado durante las ventanas de incidente, trátalo como presión real de memoria. Deja de debatir “pero RAM libre” y arregla capacidad/tuning.

Task 5: Identifica si kswapd está quemando CPU (reclaim trabajando horas extra)

cr0x@server:~$ top -b -n 1 | head -n 20
top - 10:01:22 up 41 days,  3:12,  1 user,  load average: 6.20, 5.90, 5.10
Tasks: 412 total,   2 running, 410 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.1 us,  9.3 sy,  0.0 ni, 55.0 id, 13.2 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem : 257802.0 total,   1140.2 free, 210000.4 used,  46661.4 buff/cache
MiB Swap:  16384.0 total,   8192.0 free,   8192.0 used.  43000.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  158 root      20   0       0      0      0 R  48.0   0.0  120:11.2 kswapd0
 2210 root      20   0  9820.0m  12.2g  210.0m S  30.0   4.8  300:10.9 qemu-system-x86
  901 root      20   0  2120.0m  10.0g   50.0m S   8.0   4.0   90:22.2 pvestatd

Significado: kswapd0 al ~48% CPU indica reclaim de fondo intenso.
Decisión: No estás solo “usando swap”, estás pagando CPU y latencia por ello. Investiga ARC, sobredimensión y tunables de reclaim.

Task 6: Ve qué hay realmente en RAM (anon vs file vs slab)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           252Gi       205Gi       1.1Gi       2.0Gi        45Gi        42Gi
Swap:           16Gi       8.0Gi       8.0Gi

Significado: Mucho usado es normal; céntrate en “available”. Aquí available es 42 GiB, lo que sugiere que no estás arrinconado—a menos que ZFS/VMs necesiten ráfagas.
Decisión: Si available es bajo (<~5–10% de la RAM) y la actividad de swap es alta, necesitas reducir carga o aumentar memoria. Si available es alto, enfócate en por qué el swap no se reclama (a menudo “no lo necesita”).

Task 7: Identifica los mayores consumidores de swap (por proceso)

cr0x@server:~$ for pid in $(ls /proc | grep -E '^[0-9]+$'); do awk '/^VmSwap:/ {print $2 " " pid}' pid=$pid /proc/$pid/status 2>/dev/null; done | sort -nr | head
1048576 2210
524288  4120
262144  1987
131072  901
65536   3301

Significado: PID 2210 (probablemente un proceso qemu) tiene ~1 GiB swapado.
Decisión: Si qemu está swapando intensamente, trátalo como un problema a nivel host (sobredimensión/ARC/tuning). Si un demonio aleatorio está en swap, arregla/limita ese proceso.

Task 8: Mapea PID de qemu a VMID (específico de Proxmox)

cr0x@server:~$ ps -p 2210 -o pid,cmd --no-headers
2210 /usr/bin/kvm -id 104 -name vm104 -m 16384 -smp 8 -drive file=/dev/zvol/rpool/vm-104-disk-0,if=virtio,cache=none

Significado: Ese proceso swapado es VMID 104 con 16 GiB asignados.
Decisión: Revisa la configuración de memoria de la VM (ballooning, min/max) y la sobredimensión del host. Si es una VM crítica para el negocio, prioriza estabilizar el reclaim del host.

Task 9: Comprueba la asignación de memoria de Proxmox vs física (sanidad, no perfección)

cr0x@server:~$ qm list
 VMID NAME         STATUS     MEM(MB)    BOOTDISK(GB) PID
 101  app01        running    32768             64.00 2101
 104  db01         running    16384            200.00 2210
 105  cache01      running    32768             32.00 2302
 110  winbuild     running    24576            120.00 2410

Significado: La memoria asignada suma rápido; ballooning puede ocultarlo, pero la física no miente.
Decisión: Si estás cerca o por encima de la RAM del host, para. Reduce asignaciones, aplica límites o añade nodos/RAM. “Pero los invitados no lo usan” es cómo comienzan los incidentes.

Task 10: Comprueba la configuración de ballooning para una VM

cr0x@server:~$ qm config 104 | grep -E 'memory|balloon'
balloon: 4096
memory: 16384

Significado: La VM tiene 16 GiB máximo, objetivo de balloon 4 GiB (reclaim muy agresivo).
Decisión: Si el objetivo de balloon está muy por debajo del working set real, estás forzando reclaim en el invitado y luego reclaim en el host. Considera aumentar el mínimo de balloon o desactivar ballooning para VMs sensibles a la latencia.

Task 11: Si usas ZFS, comprueba el tamaño de ARC y la presión de ARC

cr0x@server:~$ arcstat 1 1
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
10:03:41   220    12      5     3  1.3     9  3.7     0  0.0   96.0G  110.0G

Significado: El tamaño del ARC es ~96 GiB, el objetivo c ~110 GiB. Eso es mucho en un hypervisor, dependiendo de la RAM total y las necesidades de VM.
Decisión: Si ARC es grande mientras los invitados están swapando, limita ARC. La estabilidad del hypervisor vence a pequeñas ganancias de cache de lectura.

Task 12: Confirma zfs_arc_max (si está establecido) y decide si limitarlo

cr0x@server:~$ grep -R "zfs_arc_max" /etc/modprobe.d /etc/sysctl.conf /etc/sysctl.d 2>/dev/null
/etc/modprobe.d/zfs.conf:options zfs zfs_arc_max=68719476736

Significado: ARC max está fijado en 64 GiB (en bytes). Bien: al menos tiene límite.
Decisión: Si tienes reclaim frecuente y actividad de swap, baja zfs_arc_max con cuidado para dejar margen a las VMs. Si eres storage-heavy y VM-light, mantenlo más alto.

Task 13: Comprueba swappiness del kernel y comportamiento de dirty writeback

cr0x@server:~$ sysctl vm.swappiness vm.dirty_ratio vm.dirty_background_ratio
vm.swappiness = 60
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10

Significado: Swappiness 60 es algo cercano al valor por defecto. Las proporciones dirty definen cuándo el kernel comienza a forzar escrituras.
Decisión: En hypervisors, una postura común es reducir swappiness (por ejemplo, 1–10) para desalentar el swap de memoria qemu, salvo que sepas que te beneficia. Ajusta dirty ratios si ves stalls por writeback.

Task 14: Inspecciona fallos de página mayores (signo de swap-ins y misses de cache)

cr0x@server:~$ pidstat -r -p 2210 1 3
Linux 6.2.16 (server)  12/26/2025  _x86_64_ (32 CPU)

10:05:12 AM   PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
10:05:13 AM  2210   1200.00    45.00 10055680 12582912   4.8  qemu-system-x86
10:05:14 AM  2210   1100.00    60.00 10055680 12583104   4.8  qemu-system-x86
10:05:15 AM  2210   1300.00    55.00 10055680 12583360   4.8  qemu-system-x86

Significado: Los fallos mayores (majflt/s) suelen implicar I/O de disco (incluyendo swap-ins). Estos números son suficientemente altos como para preocuparse.
Decisión: Fallos mayores altos en qemu durante carga se correlacionan con swap o memoria bajo presión. Reduce la presión o mejora el dispositivo de swap y el comportamiento de reclaim.

Task 15: Comprueba el estado de THP (puede contribuir al dolor de reclaim/compactación)

cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

Significado: THP está en always. Eso puede estar bien, pero en algunas cargas de virtualización aumenta picos de latencia.
Decisión: Si ves stalls por compactación/reclaim, prueba madvise en lugar de always y mide. No lo copies sin probar: testea en un nodo primero.

Task 16: Averigua si el swap está en almacenamiento lento o contendido

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,ROTA,MOUNTPOINTS
NAME   TYPE   SIZE ROTA MOUNTPOINTS
sda    disk   1.8T    1
├─sda1 part   512M    1 /boot/efi
├─sda2 part     1G    1 /boot
└─sda3 part    16G    1 [SWAP]
└─sda4 part   1.8T    1
nvme0n1 disk  1.9T    0
└─nvme0n1p1 part 1.9T    0 /

Significado: El swap está en un disco rotativo (ROTA=1) mientras el OS está en NVMe. Eso huele a problema de rendimiento.
Decisión: Mueve el swap a almacenamiento más rápido (NVMe) o usa zram para absorber ráfagas. Swap en rotativo en un hypervisor activo es una fábrica de latencia.

Task 17: Comprueba si estás alcanzando límites de memory cgroup (especialmente contenedores)

cr0x@server:~$ systemd-cgtop -m -n 1
Control Group                           Memory Current  Memory Peak  Memory Swap  IO Read  IO Write
/                                         210.0G        211.2G        8.0G        2.1M     30.4M
/system.slice/pve-container@112.service      3.2G          3.4G        1.5G          0B       12K
/system.slice/pve-container@113.service      7.8G          8.0G        2.0G          0B       18K

Significado: Los contenedores también pueden usar swap; “memory.swap” muestra consumo de swap por cgroup.
Decisión: Si un contenedor es el tragón de swap, arregla su límite o su carga. La tunning a nivel host no hará comportarse bien a un contenedor mal dimensionado.

Task 18: Vaciar swap de forma segura (cuando ya arreglaste la causa)

cr0x@server:~$ sudo sysctl -w vm.swappiness=1
vm.swappiness = 1
cr0x@server:~$ sudo swapoff -a && sudo swapon -a
cr0x@server:~$ swapon --show
NAME      TYPE SIZE  USED PRIO
/dev/sda3 part  16G    0B   -2

Significado: El swap fue limpiado y reactivado.
Decisión: Haz esto solo cuando MemAvailable sea cómodamente alto y la actividad de swap sea baja. De lo contrario, swapoff puede desencadenar una tormenta de memoria y un evento OOM.

Tres microhistorias corporativas desde las minas de swap

Microhistoria 1: El incidente causado por una suposición equivocada

Una SaaS mediana ejecutaba un clúster Proxmox que alojaba “servicios varios” internos: runners de CI, una pila de métricas, un par de bases de datos que nadie poseía,
y una VM Windows que existía porque alguien necesitó Visio una vez. Los hosts tenían RAM de sobra en papel. El swap aún subía, despacio, como un mal humor.

La suposición equivocada fue simple: “Si free muestra decenas de gigabytes disponibles, el sistema no puede estar bajo presión de memoria.” Miraron
MemAvailable y dijeron victoria. Mientras tanto, las quejas de usuarios eran sobre congelamientos cortos—30 segundos de nada—luego todo “se ponía al día”.

La clave fue PSI. Durante los congelamientos, PSI memoria “full” se disparaba. kswapd ocupó un núcleo de CPU durante largos tramos. El I/O de swap era medible, no enorme, pero consistente.
No era falta de memoria en promedio; era falta de memoria cuando se necesitaba, y el reclaim no podía seguir el ritmo.

Causa raíz: un puñado de VMs tenía objetivos de balloon muy por debajo de sus working set reales. El host reclamaba agresivamente de los invitados, los invitados hacían paging,
y luego el host también hacía paging. Dos capas de paging crearon picos de latencia. La solución fue aburrida: desactivar ballooning para las VMs sensibles a latencia, fijar mínimos realistas
para el resto, y dejar de fingir que el overcommit es “gratis”.

El swap “siguió creciendo” tras la solución, pero la actividad de swap cayó casi a cero. Esa fue la parte importante. Dejaron de reiniciar hosts como si fuera un ritual de bienestar.

Microhistoria 2: La optimización que salió mal

Otra organización decidió “optimizar I/O” moviendo el swap a un zvol ZFS en el mismo pool que los discos de las VMs, porque era cómodo y los snapshots molaban.
Funcionó en el laboratorio. Todo funciona en el laboratorio. El laboratorio es donde la física viene a echarse una siesta.

En producción, bajo un evento leve de presión de memoria (una VM DB haciendo un rebuild de índice), la actividad de swap aumentó. ZFS empezó a trabajar más.
ARC creció porque la carga era de muchas lecturas. El pool se puso ocupado. El I/O de swap compitió con el I/O de discos de VM. La latencia subió. Los invitados se ralentizaron.

El equipo respondió aumentando el tamaño del swap. Eso redujo eventos OOM pero aumentó el tiempo pasado en miseria. Básicamente convirtieron “fallar rápido” en
“fallar lentamente mientras todos miran dashboards”.

La solución: mover el swap fuera del pool ZFS y a almacenamiento local rápido dedicado (o zram para ráfagas). Limitar ARC. Mantener el I/O de swap lejos de la misma cola
de la que dependen tus VMs. A veces la optimización correcta es separar responsabilidades, no rasurar microsegundos.

La lección quedó: “Las arquitecturas por conveniencia son el saco de boxeo favorito de producción.”

Microhistoria 3: La práctica aburrida pero correcta que salvó el día

Una compañía del ámbito financiero tenía un clúster Proxmox que nunca hacía titulares. No porque fuera mágico—porque se gestionaba con la disciplina que parece poco impresionante
hasta que falta.

Mantenían un simple informe semanal: tendencias por nodo de MemAvailable, promedios PSI, tasas de I/O de swap y principales consumidores de swap. No métricas vanidosas; las que usas
para detectar cambios lentos. También impusieron una política: las asignaciones de memoria de VM no podían exceder un umbral de margen definido sin justificarse en un ticket.

Una semana, PSI “some” subió en dos nodos. El I/O de swap se mantuvo bajo, pero la CPU de kswapd subió. Nada estaba roto aún. Ese es el mejor momento para arreglar.
Encontraron una nueva VM de ingestión de logs con un límite de memoria demasiado alto y ballooning muy bajo, provocando presión de reclaim en el host durante el pico de ingestión.

Ajustaron la memoria de la VM, pusieron un mínimo de balloon sensato y apretaron un poco zfs_arc_max. Los nodos nunca llegaron al precipicio. Sin incidente. Sin drama nocturno “¿por qué el hypervisor está swapando?”.
La gráfica aburrida salvó el día porque hizo visible lo “casi roto”.

Si quieres fiabilidad, no necesitas heroísmos. Necesitas señales tempranas y permiso para actuar sobre ellas.

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

1) Síntoma: swap usado es alto, pero el rendimiento está bien

Causa raíz: Se swapearon páginas frías y nunca se necesitaron. La actividad de swap está cerca de cero.

Solución: No hacer nada. Monitoriza PSI y I/O de swap. No ejecutes “swapoff -a” solo para sentir que quedó limpio.

2) Síntoma: swap usado crece diariamente, kswapd CPU alta, congelamientos cortos de VM

Causa raíz: Presión sostenida de memoria o bucle de reclaim; a menudo sobredimensión de VM más ZFS ARC o ballooning.

Solución: Reduce asignaciones o mueve VMs; limita ARC; baja swappiness; desactiva o restringe ballooning; verifica que PSI baje.

3) Síntoma: el host tiene mucho MemAvailable pero el I/O de swap es alto

Causa raíz: Desequilibrio de reclaim o presión por cgroup (contenedores/configs de VM), o THP/stalls de compactación que crean patrones de presión.

Solución: Inspecciona PSI y uso por cgroup; ajusta swappiness; considera THP=madvice; asegura que el dispositivo de swap sea rápido.

4) Síntoma: después de añadir swap, el sistema deja de OOMear pero se vuelve lento

Causa raíz: Convertiste una falla dura en thrashing. El swap está enmascarando problemas de capacidad.

Solución: Reajusta compromisos de RAM; mantén swap moderado; usa swap como buffer de emergencia, no como estado estacionario.

5) Síntoma: los picos de swap ocurren durante backups/scrubs

Causa raíz: Los stalls inducidos por I/O causan writeback sucio y retrasos de reclaim; los scrubs de ZFS pueden cambiar el comportamiento del cache y la presión.

Solución: Programa I/O pesado; limita ARC; ajusta dirty ratios si hay stalls por writeback; asegura que el swap no esté en el mismo dispositivo ocupado.

6) Síntoma: una VM está “bien” pero todo lo demás va lento

Causa raíz: Una VM o contenedor está forzando reclaim en el host (tragona de memoria), a menudo por memoria mal dimensionada o carga desbocada.

Solución: Identifica los mayores consumidores de swap; limita al culpable; fija memoria realista en VMs; aísla cargas ruidosas en nodos dedicados.

7) Síntoma: el swap sigue creciendo tras cambios de migración

Causa raíz: Cambios de localidad de memoria, ARC se calienta distinto, o cambian comportamientos de KSM/THP. Además: las páginas swapadas persistentes no vuelven automáticamente.

Solución: Vuelve a medir actividad de swap y PSI. Si está tranquilo, acéptalo. Si no, afina y opcionalmente vacía swap durante una ventana de mantenimiento.

Listas de comprobación / plan paso a paso

Paso a paso: estabilizar un host Proxmox que está swapping bajo carga

  1. Mide actividad, no sentimientos.
    Usa vmstat 1, PSI, y pidstat para confirmar swapping activo y stalls.
  2. Encuentra la fuente de presión.
    Identifica los mayores consumidores de swap; mapea PIDs qemu a VMIDs; revisa cgroups de contenedores.
  3. Revisa compromisos.
    Compara RAM física con la RAM total asignada. Si estás sobredimensionado sin un plan, ese es el plan fallando.
  4. Arregla la política de ballooning.
    Para VMs sensibles a latencia: desactiva ballooning o define un mínimo realista. Para el resto: mantén ballooning conservador.
  5. Limita ZFS ARC si usas ZFS.
    Decide un presupuesto: deja margen para el host + picos de VM. Aplica y supervisa.
  6. Haz el swap rápido o hazlo más pequeño.
    Pon el swap en NVMe si lo necesitas; evita colocarlo en el mismo pool contendido que los discos de VM.
  7. Ajusta reclaim con suavidad, luego mide de nuevo.
    Ajusta swappiness (común: 1–10 para hypervisors), considera THP=madvice, y observa PSI y I/O de swap.
  8. Sólo entonces vacía swap (opcional).
    Usa swapoff/swapon durante una ventana de baja carga si la ocupación de swap te molesta o necesitas una línea base limpia.
  9. Fija medidas de control.
    Alertas sobre PSI full, tasa de I/O de swap y CPU de kswapd. Un dashboard solo sirve si cambia el comportamiento.

Checklist: cómo se ve “bien” en un nodo Proxmox estable

  • MemAvailable se mantiene por encima de un umbral cómodo en picos normales (defínelo; no lo adivines).
  • PSI memoria “full” está cerca de cero la mayor parte del tiempo; “some” es bajo y estable.
  • La I/O de swap es casi cero en estado estable; la ocupación de swap puede ser no nula y eso es aceptable.
  • kswapd no es un consumidor principal de CPU.
  • ZFS ARC está limitado (si se ejecuta ZFS) y no deja a los invitados sin memoria.
  • El ballooning es deliberado, no un caos por defecto.

Checklist: cuándo añadir RAM vs cuándo tunear

  • Añadir RAM cuando PSI muestra stalls sostenidos y no puedes reducir compromisos sin impacto de negocio.
  • Tunear cuando la actividad de swap es alta pero hay margen disponible, o cuando una elección de configuración (ARC/ballooning/dispositivo de swap) está obviamente mal.
  • Rearquitectar cuando tu objetivo de densidad requiere overcommit permanente y no tienes predictibilidad de cargas. Eso es una decisión estratégica, no un sysctl.

FAQ

1) ¿Por qué el uso de swap sigue aumentando aunque la RAM “parezca bien”?

Porque el uso de swap es pegajoso. Linux puede swapear páginas frías y no molestarse en traerlas de vuelta si no hacen falta. Si la I/O de swap es baja y PSI está calmado,
no es necesariamente un problema.

2) ¿Debería poner vm.swappiness=1 en Proxmox?

A menudo sí para hypervisors, porque swapear memoria qemu perjudica la latencia. Pero no lo trates como un número mágico. Mide la I/O de swap y PSI antes y después.
Si ejecutas cargas con mucho file cache o ZFS, todavía necesitas gestionar ARC y los compromisos.

3) ¿Es seguro operar sin swap?

Es “seguro” en el sentido de que te toparás con OOM más rápido y de forma más dura. Algunos entornos prefieren eso a thrashing. La mayoría de hypervisors de producción mantienen algo de swap
como buffer de emergencia, pero confían en la planificación de capacidad para que el swap no se use en carga normal.

4) Mi swap está usado pero swap-in/out es cero. ¿Debería limpiarlo?

No hay prisa. Limpiar el swap fuerza a esas páginas de vuelta a RAM, lo que puede causar presión transitoria. Si quieres una línea base limpia, vacíalo durante una ventana de mantenimiento
con suficiente MemAvailable.

5) ¿ZFS ARC “causa” el swapping?

ARC no fuerza directamente el swap, pero compite por RAM. Si permites que ARC crezca mucho en un hypervisor, el kernel puede reclamar páginas anónimas
(tus VMs) mientras ARC sigue grande. Limitar ARC es una medida común para estabilizar Proxmox+ZFS.

6) ¿Debería el swap vivir en un zvol ZFS?

Puedes, pero normalmente no deberías en un hypervisor ocupado. El I/O de swap compite con el I/O de disco de las VMs y puede amplificar la latencia. Prefiere almacenamiento local rápido
dedicado o zram para absorción de ráfagas, según tus restricciones.

7) ¿El memory ballooning es bueno o malo?

Es una herramienta. Es bueno cuando la usas para reclamar memoria verdaderamente no utilizada en invitados y defines mínimos realistas. Es malo cuando la usas como muleta para
overcommit y luego te preguntas por qué invitados y host empiezan a hacer paging bajo carga.

8) ¿Cómo sé si el swapping está perjudicando a las VMs?

Busca I/O de swap en el host (vmstat), fallos de página mayores elevados en procesos qemu, PSI memoria “full”, CPU de kswapd y síntomas a nivel VM como picos de latencia y I/O wait.
El swap usado por sí solo no basta.

9) ¿Puede THP causar crecimiento de swap?

THP trata más sobre el coste de compactación y reclaim que sobre la ocupación de swap directamente. Pero si THP en “always” provoca stalls frecuentes de compactación y churn de reclaim,
puedes ver más swapping y latencia. Si lo sospechas, prueba THP=madvice y mide.

10) ¿Cuál es la medida más fiable para estabilizar?

Deja de mentirle a la máquina sobre memoria. Mantén los compromisos dentro de la realidad física (con margen), limita ARC si usas ZFS y haz el ballooning conservador.
Luego ajusta swappiness y la ubicación del swap como refinamientos.

Conclusión: pasos siguientes que realmente estabilizan

“El swap sigue creciendo” sólo da miedo cuando va acompañado de presión y actividad. Tu trabajo es separar ocupación de thrash,
luego eliminar la razón por la que el host se ve forzado a tomar decisiones feas.

Haz esto a continuación:

  1. Captura una muestra de 10 minutos durante el pico: vmstat 1, PSI (/proc/pressure/memory), procesos top y fallos mayores por qemu.
  2. Mapea consumidores de swap a VMIDs; verifica que ballooning y tamaños de memoria no sean fantasía.
  3. Si usas ZFS: limita ARC a un presupuesto deliberado que deje margen a las VMs.
  4. Mueve el swap a almacenamiento rápido o usa zram si necesitas un buffer de ráfaga; evita pools contendidos.
  5. Pon swappiness bajo (y persístelo) una vez confirmes que mejora la actividad de swap y los stalls.
  6. Sólo tras la estabilidad: opcionalmente limpia el swap durante una ventana tranquila para reiniciar líneas base.

El objetivo no es “cero swap usado”. El objetivo es “sin stalls de memoria, sin thrash y latencia predecible”. Lo aburrido es la característica.

← Anterior
Cambios de esquema: MySQL vs PostgreSQL — ¿Quién convierte ALTER TABLE en una pesadilla?
Siguiente →
Pánico del kernel: cuando Linux dice “nope” en público

Deja un comentario