search
Linux 5 min read

RAM → zram → swap en disco: cómo montar un sistema de swap por capas y probarlo con stress-ng

Pablo IB

TL;DR: Crea un swapfile de 16 GB con chattr +C (Btrfs) y ponle prioridad 50 en fstab. El kernel usará zram primero y desbordará al disco solo cuando zram se llene. Lo probé con stress-ng: 22 GB extra absorbidos, sistema volvió a la normalidad sin reiniciar.


zram comprime en RAM. El swapfile escribe en disco. Juntos crean un sistema de memoria por capas: lo activo en RAM, lo tibio en zram, lo frío en disco.

La parte importante no es la configuración — es verificar que funciona. Así que lo probé con stress-ng, allocando memoria hasta saturar todo.


El sistema de capas

RAM física (lo que usas ahora)
  → zram (swap comprimido en RAM, prioridad 100)
    → swapfile (swap en disco NVMe, prioridad 50)
CapaCapacidadPrioridadVelocidad
RAM física32 GBInstantánea
zram16 GB100 (primero)~2x más lento que RAM
swap disco16 GB50 (último)~100x más lento que RAM
Total~64 GB

Crear el swapfile

Btrfs: desactivar CoW (obligatorio)

Btrfs usa Copy-on-Write por defecto. Sin desactivarlo, cada escritura de swap genera el doble de I/O:

sudo truncate -s 0 /swapfile
sudo chattr +C /swapfile     # ← Obligatorio en Btrfs
sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile

# Verificar CoW desactivado
sudo lsattr /swapfile
# Debe mostrar: ---------------C------ /swapfile

ext4 / xfs

No necesitan chattr +C:

sudo fallocate -l 16G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile

Configurar prioridad

Queremos que el kernel prefiera zram (rápido) antes que el disco (lento):

sudo swapon -p 50 /swapfile

En /etc/fstab para que persista:

/swapfile none swap defaults,pri=50 0 0

Verificar

swapon --show
# NAME       TYPE       SIZE  USED PRIO
# /dev/zram0 partition  16G   3.8G  100  ← zram, prioridad alta
# /swapfile  file       16G     0B   50  ← disco, prioridad baja

El test: stress-ng hasta saturar

No me fié de la teoría. Probé con stress-ng, allocando memoria en incrementos de 4 GB:

# Paso 1: Allocar 4 GB
stress-ng --vm 1 --vm-bytes 4G --vm-keep --timeout 600 --vm-method all &
sleep 8 && free -h && swapon --show && zramctl

# Paso 2: Otros 4 GB (total 8 GB)
stress-ng --vm 1 --vm-bytes 4G --vm-keep --timeout 600 --vm-method all &
sleep 8 && free -h && swapon --show && zramctl

# ... repetir hasta saturar

Resultados paso a paso

FaseRAM usadaRAM librezram usadoswap discoObservación
Inicio18 GB6.2 GB1.2 MB0 BSistema en reposo
+4 GB22 GB2.4 GB1.2 MB0 Bzram aún no se activa
+8 GB26 GB3.3 GB897 MB0 B📈 zram empieza a absorber
+12 GB29 GB1.1 GB3.2 GB0 Bzram comprime 3.1 GB → 941 MB
+16 GB30 GB193 MB8.8 GB0 BRAM casi llena, zram absorbe todo
+20 GB30 GB194 MB13.7 GB0 Bzram casi lleno
+22 GB30 GB518 MB15.3 GB1.5 GB🎉 zram SATURADO → swap disco ENTRA

El momento clave: zram alcanzó 15.3 GB (100% de su capacidad) y el kernel desbordó al swapfile del disco. Exactamente el comportamiento que queríamos.

Compresión zstd en acción

zram DATA (sin comprimir)zram COMPR (comprimido)Ratio
8.5 GB2.4 GB3.5:1
13.4 GB3.6 GB3.7:1
15.1 GB4.5 GB3.4:1

zstd hizo mucho más que el ratio 2:1 que usamos para los cálculos. 15 GB de datos comprimidos en solo 4.5 GB de RAM física.

La recuperación

Después de matar los procesos:

pkill -f stress-ng
MomentoRAM usadazram usadoswap disco
Tras liberar12 GB11 GB39 MB
+30 segundos11 GB10.2 GB37 MB

El sistema volvió a la normalidad sin intervención. Sin reboot, sin OOM, sin muertes.


¿Y el desgaste del NVMe?

Las escrituras en el swapfile son de páginas que llevan horas inactivas. No es un flujo constante — es una descarga puntual. El NVMe moderno tiene TBW de 600+ TB. Escribir 16 GB de swap ocasionalmente no afecta su vida útil.


¿Por qué 16 GB y no menos?

Mi sistema tiene 32 GB de RAM y trabajo con Docker, Firefox, IDEs, servidores. 4-8 GB de swap serían insuficientes para absorber todo lo idle. 16 GB da el equivalente a un equipo de 64 GB — que es lo que realmente necesito para mi workload.


zram vs zswap: lo que dice un ingeniero del kernel

Si buscas información sobre zram, llegarás a “Debunking zswap and zram myths” de Chris Down. Chris ha trabajado en gestión de memoria del kernel casi una década, incluyendo zram en Meta/Quest.

Su posición: no uses zram si tienes disco swap. Usa zswap.

El argumento se llama LRU inversion: cuando zram se llena de páginas frías (las primeras en swap), las páginas más calientes van al disco (más lento). Es lo contrario de lo que quieres.

Por qué sigo con zram

Chris trabaja con servidores. En servidores, la LRU inversion es real porque el workload es predecible. En desktop con bursts (abrir IDE, 50 tabs de Firefox), el patrón es más caótico.

Tengo systemd-oomd. Chris menciona que sin OOM killer en userspace, zram puede dejar el sistema colgado. Yo lo tengo activo.

Mi test lo demuestra. El stress-ng verificó que el flujo funciona. Con swappiness=180, el kernel mueve páginas a zram antes de que la RAM esté llena. Para cuando zram se satura, systemd-oomd ya detectó el problema.

zswap requiere disco swap. zswap es un caché comprimido delante del disco swap. No funciona sin él.

Si tu workload es servidor con carga sostenida, sigue la guía de Chris. Si es desktop, zram con swappiness=180 funciona.


Artículos de esta serie

  1. Cómo duplicar la RAM de tu Linux con zram y swap comprimida (sin comprar nada)
  2. zram: mitad de RAM, algoritmo zstd y por qué tu distro lo tiene mal configurado
  3. Swappiness 180: el valor que hace funcionar zram (y la regla udev que te lo estaba impidiendo)
  4. RAM → zram → swap en disco: cómo montar un sistema de swap por capas y probarlo con stress-ng ← estás aquí
  5. systemd-oomd y Docker limits: lo que nadie te cuenta para proteger tu sistema

Referencias