RAM → zram → swap en disco: cómo montar un sistema de swap por capas y probarlo con stress-ng
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)
| Capa | Capacidad | Prioridad | Velocidad |
|---|---|---|---|
| RAM física | 32 GB | — | Instantánea |
| zram | 16 GB | 100 (primero) | ~2x más lento que RAM |
| swap disco | 16 GB | 50 (ú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
| Fase | RAM usada | RAM libre | zram usado | swap disco | Observación |
|---|---|---|---|---|---|
| Inicio | 18 GB | 6.2 GB | 1.2 MB | 0 B | Sistema en reposo |
| +4 GB | 22 GB | 2.4 GB | 1.2 MB | 0 B | zram aún no se activa |
| +8 GB | 26 GB | 3.3 GB | 897 MB | 0 B | 📈 zram empieza a absorber |
| +12 GB | 29 GB | 1.1 GB | 3.2 GB | 0 B | zram comprime 3.1 GB → 941 MB |
| +16 GB | 30 GB | 193 MB | 8.8 GB | 0 B | RAM casi llena, zram absorbe todo |
| +20 GB | 30 GB | 194 MB | 13.7 GB | 0 B | zram casi lleno |
| +22 GB | 30 GB | 518 MB | 15.3 GB ✅ | 1.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 GB | 2.4 GB | 3.5:1 |
| 13.4 GB | 3.6 GB | 3.7:1 |
| 15.1 GB | 4.5 GB | 3.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
| Momento | RAM usada | zram usado | swap disco |
|---|---|---|---|
| Tras liberar | 12 GB | 11 GB | 39 MB |
| +30 segundos | 11 GB | 10.2 GB | 37 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
- Cómo duplicar la RAM de tu Linux con zram y swap comprimida (sin comprar nada)
- zram: mitad de RAM, algoritmo zstd y por qué tu distro lo tiene mal configurado
- Swappiness 180: el valor que hace funcionar zram (y la regla udev que te lo estaba impidiendo)
- RAM → zram → swap en disco: cómo montar un sistema de swap por capas y probarlo con stress-ng ← estás aquí
- systemd-oomd y Docker limits: lo que nadie te cuenta para proteger tu sistema
Referencias
- ArchWiki — zram
- Pop!_OS zram tuning
- Chris Down — Debunking zswap and zram myths — la crítica más fundamentada contra zram+disco swap
- linuxblog.io — Running Out of RAM on Linux? Add Zram — buena guía práctica