Conoces el momento. El servidor “tiene mucha RAM”, los gráficos parecían bien ayer, y ahora SSH se pausa entre pulsaciones como si estuviera replanteándose su vida.
La media de carga sube, los discos están encendidos, y cada petición de reinicio de un desarrollador suena a amenaza.
ZRAM y zswap pueden marcar la diferencia entre una desaceleración elegante y una caída total. También pueden ser la razón por la que tu CPU se queda al 100% haciendo cosplay de compresión mientras la latencia arde.
Debian 13 te da suficientes perillas para salvar el sistema —o para construir un modo de fallo muy eficiente.
El modelo mental: qué hacen realmente zram y zswap
ZRAM: un dispositivo de bloque comprimido viviendo en RAM
ZRAM crea un dispositivo de bloque respaldado por RAM (como /dev/zram0) y permite que el kernel lo trate como un dispositivo de swap.
Cuando el kernel decide sacar una página, esa página puede aterrizar en zram, comprimida.
El “disco” es memoria, pero ganas capacidad efectiva porque las páginas se comprimen. Pagas en ciclos de CPU.
Piensa en zram como “swap sin almacenamiento”, lo cual suena paradójico hasta que recuerdas: las páginas a menudo son compresibles (rellenas de ceros, datos repetitivos, basura antigua del heap, JSON cacheado que no deberías haber guardado, etc.).
En apuros, comprimir 4 GiB de páginas frías a 2 GiB de RAM es una victoria. Comprimir 4 GiB a 3.9 GiB es solo una forma costosa de decepcionarse.
Zswap: una caché comprimida delante de un dispositivo de swap real
Zswap es diferente. No es un dispositivo de swap. Es una caché para páginas swapadas, almacenada comprimida en RAM, situada delante de tu swap real (partición o swapfile).
Cuando las páginas se envían a swap, zswap intenta mantenerlas comprimidas en memoria. Si el pool de zswap se llena, expulsa páginas al dispositivo de swap real.
Esto hace de zswap un “reductor de escrituras” y suaviza la latencia: menos escrituras a SSD/HDD, menos IO aleatorio bajo presión, mejores latencias cola cuando el sistema está thrashing.
Pero aún depende de tener un backend de swap adecuado. Sin dispositivo de swap, no hay red de seguridad de zswap.
La diferencia operacional que importa
- zram puede reemplazar el swap en disco en sistemas pequeños, o convertirse en la “capa de swap rápida” delante del disco si también mantienes swap en disco.
- zswap es una caché; reduce IO de swap pero no reemplaza la capacidad de swap.
- Ambos son formas de intercambiar CPU por memoria. En CPUs modernas, ese intercambio suele ser bueno. En sistemas muy cargados, puede ser ruinoso.
Una idea parafraseada a menudo atribuida a Jim Gray: “Mide antes de tunear; la mayoría del tuning es conjetura sin datos.” (idea parafraseada)
La compresión de memoria es un ejemplo perfecto. Es fácil ser ingenioso. Es más difícil acertar.
Broma #1: La compresión de memoria es como envasar al vacío tu armario. Funciona genial hasta que necesitas esa única camisa durante un simulacro de incendio.
Hechos y contexto: cómo llegamos aquí (y por qué importa)
Un poco de contexto convierte “trastear knobs del kernel al azar” en ingeniería real. Aquí hay algunos hechos concretos para tener en mente:
- zram empezó como “ramzswap” hace años, luego fue renombrado y subido al upstream; la idea siempre fue “swap comprimido en RAM”, no una caché general.
- zswap se integró como un backend frontswap, lo que significa que se conecta al subsistema de swap como una capa de caché en lugar de un dispositivo de bloque.
- Los algoritmos de compresión cambiaron las reglas: LZO fue popular al principio por velocidad; LZ4 se volvió común; ZSTD ganó tracción por mejores ratios a un coste aceptable.
- La contabilidad de memoria de Linux se volvió más estricta con el tiempo (cgroups v2, PSI, mejor comportamiento de reclaim), haciendo que “se siente más lento” sea rastreable con señales reales.
- Chrome y navegadores modernos normalizaron el swap en escritorios: grandes conjuntos de trabajo con muchas pestañas frías, altamente compresibles en algunos lugares.
- Los SSD hicieron viable el swap pero no gratuito: la latencia es buena comparada con discos giratorios, pero escrituras aleatorias sostenidas bajo presión aún matan la latencia de cola y pueden amplificar el desgaste.
- Los contenedores volvieron el swap un tema político: algunas organizaciones prohíben swap en nodos, otras dependen de él; la compresión de memoria se vuelve un término medio cuando quieres gracia sin engañarte.
- Los valores por defecto del kernel son conservadores: la mayoría de las distribuciones evitan defaults agresivos para zram/zswap porque un “default equivocado” se convierte en una pesadilla de soporte.
- La fortaleza de Debian es la previsibilidad, por eso a menudo tienes que optar por cosas sofisticadas —y por eso debes probar como un adulto cuando lo haces.
Cuándo zram/zswap salva tu servidor (y cuándo no)
Usa zram cuando: necesitas “algo de swap” pero el almacenamiento es lento, frágil o inexistente
zram brilla en:
- VM pequeñas donde el almacenamiento del hipervisor es ruidoso o sobreaprovisionado y el IO de swap causa problemas a nivel de clúster.
- Equipos edge con flash barato donde el desgaste por swap es una preocupación real.
- Portátiles de desarrollador con presión de memoria episódica: compilaciones, navegadores, IDEs y “olvidé que Docker estaba corriendo”.
- Sistemas con abundante CPU libre y presión de memoria moderada: el costo de compresión se mantiene bajo control.
Lo que compras: la capacidad de evitar kills por OOM en presión leve a moderada y una reducción del churn de swap en disco.
Lo que no compras: memoria infinita. Si tu conjunto de trabajo realmente supera la RAM por mucho, zram solo cambia cómo fallas.
Usa zswap cuando: quieres mantener swap real, pero hacerlo menos terrible
zswap brilla cuando ya tienes swap en SSD/NVMe (o incluso HDD) y quieres suavizar el peor comportamiento bajo reclaim:
- Bases de datos y JVMs donde incluso pequeñas latencias de swap-in pueden crear latencias de cola largas, pero aún quieres una válvula de escape bajo presión.
- Hosts de VM donde tormentas de IO de swap causan contención de almacenamiento; zswap reduce la amplificación de escrituras.
- Cargas mixtas donde “algunas páginas son frías y compresibles” es cierto, pero no puedes predecir cuáles.
No te sirve cuando: el cuello de botella no es la presión de memoria
Si ya estás limitado por CPU, añadir compresión es como contratar un contable durante un incendio en la cocina porque “es bueno con los números”.
Si estás limitado por IO debido a cargas de disco no relacionadas, zswap puede ayudar reduciendo IO de swap —pero no arreglará la contención de disco subyacente.
Verdad dura: la compresión no sustituye la planificación de capacidad
zram/zswap son excelentes herramientas de “degradación elegante”. No son una licencia para ejecutar 28 GiB de servicios en una VM de 16 GiB.
Si tu conjunto de trabajo en estado estable es mayor que la RAM, la solución correcta es más RAM, menos carga, o ambas.
La compresión puede comprarte tiempo. Rara vez te compra tranquilidad.
Cómo falla: modos de fallo que parecen “Linux va lento”
Fallo #1: saturación de CPU por compresión
El modo de fallo más común es simple: el sistema está bajo presión de memoria, empieza a swapear, y ahora también está comprimiendo/descomprimiendo.
Si tus CPUs ya están ocupadas, ese trabajo extra te empuja a una espiral mortal: menos CPU para la aplicación, más stalls, más backlog, más churn de memoria.
Esto ocurre mucho con:
- nodos web ocupados con asignaciones por petición y alta presión de GC,
- runners de CI haciendo muchas compilaciones paralelas,
- cualquier caja donde intentaste “arreglar memoria” activando ZSTD a un nivel de compresión alto sin medir.
Fallo #2: falsa sensación de estabilidad (“ya no hace OOM”) seguida de colapso de latencia
zram en especial puede convertir un OOM inmediato en un periodo prolongado de miseria.
El sistema no muere. Solo se vuelve inusable: picos de latencia interactiva, timeouts RPC, reseteos de watchdog, y el on-call aprende nuevas malas palabras.
En servidores, la pregunta correcta no es “¿evitamos OOM?” sino “¿preservamos los SLOs?”
A veces matar un proceso rápido es más amable que mantener todo medio vivo durante 20 minutos.
Fallo #3: reclaim peleando con tu carga
La actividad de swap no es inherentemente mala, pero el reclaim agresivo puede serlo.
Si el conjunto caliente de tu carga es grande y cambia constantemente (por ejemplo, caches que churnean, trabajos analíticos, o métricas de alta cardinalidad), el kernel puede expulsar páginas que necesitarás de nuevo pronto.
Con zram/zswap, ahora pagas overhead extra por un ciclo de “comprimir, almacenar, descomprimir, fallar de nuevo”.
Fallo #4: pools mal dimensionados y sorpresas de “prioridad de swap”
Puedes ejecutar swap en disco y zram juntos. El kernel elige según la prioridad de swap.
Si te equivocas ahí puedes empujar páginas al disco primero, dejando zram mayormente inactivo mientras tu SSD chilla.
O al revés: puedes llenar zram demasiado agresivamente, dejando poca RAM real para page cache y conjuntos calientes de aplicaciones.
Fallo #5: pool de zswap lleno + backend lento = precipicio repentino
zswap se ve genial hasta que el pool se llena. Entonces tiene que expulsar al backend de swap real.
Si ese backend es lento o está contendido, pasas de “agradable” a “ay no” rápidamente.
No es que zswap fallara; es que vivías con latencia prestada.
Broma #2: Activar compresión de swap sin medir es como instalar un turbo en una carretilla. Va más rápido hasta que se topa con la física.
Guía de diagnóstico rápido (primeras/segundas/terceras comprobaciones)
Cuando una máquina Debian 13 está “lenta” y sospechas presión de memoria, no empieces editando knobs de sysctl.
Empieza respondiendo tres preguntas: ¿Estamos bajo presión de memoria? ¿Estamos swapando? ¿El dolor es CPU o IO?
Primero: confirma la presión y quién la está causando
- Comprueba PSI (pressure stall information): ¿las tareas están paradas esperando reclaim de memoria?
- Revisa fallos mayores y swap-ins: ¿estamos paginando activamente?
- Identifica los principales ofensores por RSS/anon y si están creciendo.
Segundo: determina si la compresión ayuda o perjudica
- Perfil de CPU a simple vista: ¿está caliente
kswapd? ¿está corriendokcompactd? ¿Estamos quemando CPU en rutas de compresión? - Estadísticas de zram: ¿qué tan lleno, qué ratio de compresión, qué tasas de lectura/escritura?
- Estadísticas de zswap: tamaño del pool, páginas almacenadas, contadores de reject/duplicate, y expulsiones al disco.
Tercero: elige la mitigación menos mala
- Si el sistema está thrashing: reduce la concurrencia, aligera la carga, para jobs por lotes, o reinicia temporalmente al mayor consumidor de memoria.
- Si el backend de swap es el cuello de botella: habilita/ajusta zswap o añade una pequeña capa zram con la prioridad correcta.
- Si la CPU es el cuello de botella: baja el coste de compresión (elección de algoritmo), o desactiva la compresión y acepta OOM más rápido.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estas tareas están pensadas para correr en un host real Debian 13. Cada tarea incluye: un comando, qué significa la salida y qué decisión puedes tomar.
Nada de esto es magia. Es solo observación disciplinada.
Task 1: Verify whether zram devices exist and are used
cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,ROTA,MOUNTPOINTS
NAME TYPE SIZE ROTA MOUNTPOINTS
vda disk 80G 1
├─vda1 part 79G 1 /
└─vda2 part 1G 1 [SWAP]
zram0 disk 8G 0
Significado: zram0 está presente y aparece como disco. El tamaño es el tamaño virtual configurado.
El swap en disco es vda2.
Decisión: Si esperas zram pero no lo ves, no lo estás usando. Si lo ves pero es muy pequeño/grande, valida el dimensionado.
Task 2: Check active swap devices and priorities
cr0x@server:~$ swapon --show=NAME,TYPE,SIZE,USED,PRIO
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 8G 512M 100
/dev/vda2 partition 1G 0B -2
Significado: zram tiene mayor prioridad (100) por lo que se usará antes que /dev/vda2.
Decisión: Si tu swap en disco tiene mayor prioridad que zram, arréglalo a menos que tengas una razón deliberada.
Task 3: Measure overall memory and swap pressure quickly
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 15Gi 12Gi 320Mi 1.1Gi 2.9Gi 1.2Gi
Swap: 9.0Gi 1.0Gi 8.0Gi
Significado: “available” es el número clave para margen a corto plazo. El swap usado indica que hemos empezado a expulsar.
Decisión: Si available es bajo y el swap está creciendo, estás en territorio de reclaim. Pasa a PSI y vmstat a continuación.
Task 4: Check memory PSI to see if the kernel is stalling tasks
cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.42 avg60=0.30 avg300=0.18 total=43832490
full avg10=0.07 avg60=0.05 avg300=0.02 total=8203491
Significado: “some” muestra contención de reclaim; “full” indica stalls severos donde las tareas no pueden avanzar por presión de memoria.
Decisión: Si “full avg10” es no trivial para un servicio sensible a latencia, ya no estás en “tunear” sino en mitigación: reduce carga, mata ofensores, añade RAM.
Task 5: Watch swap-in/out and reclaim behavior live
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 1 942080 332000 60200 812000 120 240 14 90 820 1280 40 10 35 15 0
1 2 954368 318000 60180 810500 200 420 0 140 900 1400 45 12 28 15 0
3 1 990720 290000 60150 808900 320 500 0 210 1050 1600 52 13 20 15 0
2 2 1015808 270000 60120 807400 410 690 0 260 1120 1750 55 15 16 14 0
2 1 1048576 250000 60090 805100 300 520 0 180 980 1500 50 13 22 15 0
Significado: si/so son swap-ins/outs por segundo. Valores sostenidos no nulos sugieren paginación activa.
El wa de CPU indica espera de IO; si sube durante swapping, el backend de swap puede ser doloroso.
Decisión: Un si alto sugiere que estás pagando el coste ahora (page faults al traer de vuelta). Un so alto sugiere que estás empujando páginas fuera. En cualquier caso, encuentra el consumidor de memoria y decide: matar/reiniciar/ralentizar.
Task 6: Determine if the box is slow due to disk swap IO
cr0x@server:~$ iostat -xz 1 3
Linux 6.12.0 (server) 12/30/2025 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
45.12 0.00 9.20 18.44 0.00 27.24
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz aqu-sz %util
vda 2.00 48.00 0.00 0.00 3.50 24.00 120.00 4096.00 0.00 0.00 45.00 34.13 5.40 98.00
Significado: Utilización cercana al 100% y await alto en el dispositivo backend de swap significa que tu almacenamiento es un cuello de botella.
Decisión: Si el disco está saturado durante swapping, zswap puede ayudar. Si ya está habilitado y sigue saturado, el backend es demasiado lento o el sistema está sobreasignado.
Task 7: Inspect zram compression ratio and current usage
cr0x@server:~$ cat /sys/block/zram0/mm_stat
786432000 196608000 131072 0 0 0 0 0
Significado: Los campos varían por kernel, pero típicamente incluyen: tamaño de datos originales, tamaño comprimido y metadatos.
Aquí, ~750MB de páginas originales comprimidas a ~187MB: un buen ratio.
Decisión: Si el tamaño comprimido está cerca del original, zram te está dando poco beneficio; considera un algoritmo más rápido, reducir zram o desactivar si la CPU sufre.
Task 8: Check which algorithm zram uses
cr0x@server:~$ cat /sys/block/zram0/comp_algorithm
lzo [lz4] zstd
Significado: El algoritmo entre corchetes está activo (lz4).
Decisión: Para servidores, prefiere lz4 por velocidad a menos que hayas demostrado que ZSTD mejora el ratio lo suficiente para reducir significativamente el paging.
Task 9: Verify whether zswap is enabled and what it’s doing
cr0x@server:~$ cat /sys/module/zswap/parameters/enabled
Y
cr0x@server:~$ grep -H . /sys/kernel/debug/zswap/*
/sys/kernel/debug/zswap/pool_total_size: 268435456
/sys/kernel/debug/zswap/stored_pages: 23144
/sys/kernel/debug/zswap/same_filled_pages: 120
/sys/kernel/debug/zswap/duplicate_entry: 340
/sys/kernel/debug/zswap/reject_reclaim_fail: 0
/sys/kernel/debug/zswap/reject_compress_poor: 42
/sys/kernel/debug/zswap/written_back_pages: 1800
Significado: zswap está habilitado. Está almacenando páginas en el pool, rechazando algunas por mala compresión y escribiendo algunas de vuelta a disco.
Decisión: Una tasa alta de written_back_pages junto con disco lento sugiere que el pool es demasiado pequeño, la presión de memoria es muy alta, o el backend de swap es el verdadero problema.
Task 10: Confirm the kernel swap policy knobs (swappiness and friends)
cr0x@server:~$ sysctl vm.swappiness vm.vfs_cache_pressure vm.page-cluster
vm.swappiness = 60
vm.vfs_cache_pressure = 100
vm.page-cluster = 3
Significado: swappiness influye qué tan ansiosamente el kernel swapea vs reclaima page cache. page-cluster afecta patrones de readahead de swap.
Decisión: Si ejecutas swap solo en zram en una caja sensible a latencia, considera bajar swappiness (a menudo 10–30) para evitar swapear páginas anónimas con demasiada facilidad. Mide después.
Task 11: Identify top memory consumers (RSS/anon) without fooling yourself
cr0x@server:~$ ps -eo pid,comm,rss,%mem --sort=-rss | head -n 10
PID COMMAND RSS %MEM
2210 java 4123456 26.1
1842 postgres 2104320 13.3
3011 node 1456896 9.2
1123 prometheus 802560 5.1
Significado: RSS es resident set size: lo que está actualmente en RAM. Bajo presión, RSS puede bajar mientras el rendimiento colapsa porque el proceso está faltando páginas dentro/fuera.
Decisión: Si un proceso es enorme y está creciendo, o lo limitas (límites), lo ajustas (heap, caches), o lo tratas como un incidente. No “añadas más zram” para evitar la conversación.
Task 12: Check major page faults to confirm real paging pain
cr0x@server:~$ pidstat -r 1 3
Linux 6.12.0 (server) 12/30/2025 _x86_64_ (8 CPU)
12:20:01 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
12:20:02 PM 1000 2210 2300.00 12.00 6123456 4123456 26.1 java
12:20:02 PM 1000 1842 820.00 6.00 3256780 2104320 13.3 postgres
12:20:03 PM 1000 2210 2500.00 20.00 6123456 4123456 26.1 java
Significado: Los fallos mayores (majflt/s) requieren acceso a disco o swap (o al menos una ruta de fallo no trivial). Si los fallos mayores suben con picos de latencia, estás paginando con rabia.
Decisión: Si los fallos mayores son sostenidos, céntrate en reducir el conjunto de trabajo y el churn de swap. La compresión puede ayudar si reduce IO de disco; no arreglará una carga sobredimensionada.
Task 13: Confirm cgroup v2 memory limits (container hosts love to lie)
cr0x@server:~$ cat /sys/fs/cgroup/memory.max
max
cr0x@server:~$ cat /sys/fs/cgroup/memory.current
12582912000
Significado: Sin límite de cgroup en la raíz; el uso actual es ~11.7GiB. Para contenedores/servicios, revisa sus cgroups individuales también.
Decisión: Si un servicio tiene un límite demasiado estricto, puede thrashear dentro de su cgroup aunque el host tenga memoria. Arregla el límite antes de tunear swap.
Task 14: Check zram activity rates via /proc/swaps and /proc/vmstat
cr0x@server:~$ cat /proc/swaps
Filename Type Size Used Priority
/dev/zram0 partition 8388604 524288 100
/dev/vda2 partition 1048572 0 -2
cr0x@server:~$ egrep 'pswpin|pswpout' /proc/vmstat
pswpin 184233
pswpout 392001
Significado: Los contadores totales de swap-in/out te permiten correlacionar “periodos lentos” con paginación.
Decisión: Si pswpin sube durante incidentes, estás pagando la latencia de swap. Si solo pswpout sube, estás empujando páginas fuera (quizá proactivamente por swappiness).
Consejos de ajuste: las perillas que importan en Debian 13
Elige tu estrategia: solo zram, solo zswap, o una configuración escalonada
Aquí va la postura para producción:
- zram-only: bueno para sistemas pequeños y dispositivos edge donde el swap en disco es inaceptable. Riesgo: thrash prolongado en vez de OOM rápido.
- zswap-only: mejor opción general cuando ya tienes swap en SSD/NVMe. Reduce IO sin pretender que la RAM sea infinita.
- escalonado (zram + swap en disco): potente cuando configuras prioridades correctamente. zram absorbe el churn; el swap en disco es el último recurso.
Elección de algoritmo: no seas listo antes de estar estable
Para zram y zswap, la elección de algoritmo es una decisión de política:
- LZ4: rápido, ratio decente, usualmente la opción más segura por defecto en servidores.
- LZO: también rápido, a veces ratio ligeramente peor que LZ4.
- ZSTD: mejor ratio, mayor coste de CPU; puede ser excelente si evita IO de disco, desastroso si la CPU ya está justa.
Mi regla: si estás diagnosticando un incidente, elige velocidad. Si diseñas un setup estable en una máquina con CPU abundante, experimenta con ZSTD —pero mide “full” PSI y latencia de cola.
Dimensionar zram: deja de tratarlo como RAM gratis
Consejos comunes de tamaño de zram flotan como medicina de folk (25%, 50%, “igual a la RAM”, etc.).
En producción, el tamaño de zram es sobre lo que quieres que el sistema sobreviva, no sobre lo que quieres que finja.
- En servidores: empieza alrededor de 10–25% de la RAM si lo usas como capa rápida, no como muleta de capacidad.
- En portátiles/escritorios: 25–50% de la RAM suele ser razonable porque las cargas interactivas se benefician y puedes tolerar algo de overhead de CPU.
- En sistemas tiny (≤ 2–4 GiB RAM): zram puede ser proporcionalmente mayor, pero cuidado: la CPU de núcleos pequeños puede ser el cuello de botella.
Dimensionado de zswap: controla el pool y el comportamiento de expulsión
El pool de zswap tiene un máximo como porcentaje de RAM y usa un asignador (a menudo zbud/z3fold) que intercambia densidad por CPU y características de fragmentación.
Si el pool es demasiado pequeño, escribirás de vuelta al disco rápidamente y perderás el punto. Si es demasiado grande, y desplazas page cache y páginas anónimas calientes.
Un inicio sensato para servidores con swap en SSD suele ser un tope de pool en el rango de 10–20% de RAM.
Si frecuentemente alcanzas writeback con carga normal, estás infra-provisionado o tu carga es lo suficientemente espigada como para revisar límites y concurrencia.
Swappiness: no vas a ganar un argumento de política con un solo entero
vm.swappiness no es “cuánto swap quiero”. Es parte de un sistema de decisión sobre reclamar page cache vs memoria anónima.
Con zswap, un swappiness más alto puede estar bien porque los swap-outs podrían quedarse en RAM comprimidos, reduciendo IO. Con zram-only, un swappiness muy alto puede causar churn innecesario.
Recomendación práctica:
- Servidores sensibles a latencia: empieza alrededor de 10–30 y prueba.
- Cajas de propósito general: los valores por defecto (60) pueden estar bien, especialmente con zswap.
- Servicios pesados en cache: quizá quieras un valor mayor si reclamar page cache es deseable, pero solo si entiendes las compensaciones.
Qué deberían estandarizar los administradores de Debian 13
Estandariza dos cosas en flotas:
- Visibilidad: exporta PSI (
/proc/pressure/*), swap-in/out (/proc/vmstat) y estadísticas de zram/zswap. Si no lo ves, culparás a “Linux”. - Política: decide por clase de nodo si el swap está permitido y si será zswap, zram o ambos. La consistencia vence a la astucia a las 3 a.m.
Tres microhistorias corporativas desde el campo
Microhistoria 1: El incidente causado por una suposición equivocada
Una compañía mediana operaba una flota de VMs Debian para APIs internas. El equipo de plataforma habilitó zswap en las imágenes nuevas.
La suposición era ordenada: “zswap significa que swapear es barato ahora, así que podemos dejar de preocuparnos por tormentas de swap.”
También redujeron silenciosamente el tamaño de swap a “por si acaso”, porque no querían que el uso de disco sorprendiera a nadie.
Meses después, un despliegue rutinario aumentó el uso de memoria por unos pocos cientos de megabytes por instancia.
Nada dramático. Ningún proceso se volvió loco. Ese tipo de subida lenta que hace que las gráficas parezcan colinas suaves.
Bajo carga pico, los nodos empezaron a fallar por timeout. No se caían—hacían timeout. Los retries subieron, lo que aumentó la carga, lo que incrementó el churn de memoria. Clásico.
El on-call descubrió zswap habilitado y saludable. El pool se llenó y luego empezó a escribir de vuelta al swap de backend.
Pero el swap de backend era pequeño, así que también se llenó rápido. Una vez que el swap está lleno, el kernel tiene menos opciones; obtienes presión de reclaim, stalls y eventualmente OOM —a menudo en el peor momento posible.
El sistema no tenía una red de seguridad grande; tenía una trampa de swap pequeña.
La solución fue aburrida: restaurar un tamaño razonable del backend de swap, mantener zswap, y alertar sobre la saturación del pool de zswap y la tasa de crecimiento del uso de swap.
El equipo también añadió una comprobación de “presupuesto de memoria” al despliegue: pequeños incrementos por nodo pueden convertirse en grandes patrones de fallo en la flota.
Microhistoria 2: La optimización que salió mal
Otra org operaba runners de CI en Debian. Las compilaciones estaban paralelizadas agresivamente, y se esperaba presión de memoria.
Alguien leyó que ZSTD tenía mejores ratios de compresión y decidió “mejorar el rendimiento” cambiando zram a ZSTD en todas partes.
El cambio se veía genial en una prueba tranquila: el uso de swap bajó y la “memoria libre” parecía mejor.
En producción, la CPU era el recurso realmente escaso. Esos runners ya estaban ocupados compilando, enlazando, comprimiendo artefactos y haciendo handshakes criptográficos con registros.
Cuando llegó la presión de memoria, el sistema empezó a comprimir páginas con ZSTD. La CPU pasó de “ocupada pero bien” a “saturada y caótica”.
Los tiempos de compilación aumentaron. Los tiempos en cola subieron. Los ingenieros añadieron más trabajos paralelos para compensar, lo que lo empeoró.
La pista estaba en las métricas que no estaban mirando: PSI de memoria “full” subía en horas pico, y el steal de CPU en el hipervisor aumentó mientras todos peleaban por ciclos.
El “mejor ratio de compresión” era irrelevante; el sistema no necesitaba más capacidad efectiva de swap. Necesitaba menos overhead de CPU bajo contención.
Revirtieron a LZ4, redujeron ligeramente el tamaño de zram y añadieron una política de scheduling para limitar compilaciones concurrentes según la memoria disponible y umbrales de PSI.
El resultado neto: menos trucos heroicos del kernel, mejor rendimiento y menos ralentizaciones misteriosas.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Un servicio relacionado con pagos (siempre divertido) corría en Debian con un estricto presupuesto de latencia. El equipo SRE tenía una política: swap permitida, pero solo con zswap, y solo con alertas específicas.
Controlaban PSI de memoria, tasa de swap-in y tiempos de await del disco. Nada sofisticado. Solo visibilidad consistente.
Una tarde llegó un pico de tráfico junto con un cambio de configuración aparentemente inocuo que aumentó el caching en memoria.
El uso de memoria subió y empezó el reclaim. La clave fue que el sistema no cayó de inmediato; zswap absorbió swap-outs tempranos, reduciendo escrituras a disco.
Pero las alertas saltaron: PSI de memoria “full” subió un poco, y las páginas escritas de zswap empezaron a aumentar —una señal temprana de que el pool se estaba llenando.
El on-call no adivinó. Siguió el runbook: reducir tamaño de cache, bajar la concurrencia de workers y escalar horizontalmente.
Sin reinicios dramáticos. Sin “probemos zram también.” Solo mitigación controlada mientras se mantenían los SLOs.
El incidente fue una no-evento: una página, una respuesta y una corrección antes de que los clientes lo notaran.
La práctica que los salvó fue aburrida: tenían indicadores adelantados. El uso de swap es un indicador rezagado; cuando es grande ya estás pagando.
PSI y el writeback de zswap les dieron una oportunidad para actuar antes de que la máquina se convirtiera en una presentación de diapositivas.
Errores comunes: síntomas → causa raíz → solución
1) Síntoma: la media de carga es alta, la CPU alta, pero nada “parece” ocupado
Causa raíz: hilos del kernel están quemando CPU en reclaim y compresión de páginas (kswapd, colas de trabajo de compresión), a menudo desencadenado por zram/zswap bajo presión.
Solución: confirma con PSI y vmstat. Si la CPU es la restricción, cambia a un algoritmo más rápido (LZ4), reduce zram, baja la concurrencia o desactiva la compresión temporalmente para forzar un OOM y recuperación más rápidos.
2) Síntoma: los discos alcanzan 100% de uso durante “incidentes de memoria”
Causa raíz: el backend de swap está recibiendo escrituras/lecturas intensas; zswap puede estar deshabilitado, mal configurado o demasiado pequeño; la prioridad de zram puede estar equivocada.
Solución: habilita zswap (con un dispositivo de swap real), asegura que zram (si se usa) tenga mayor prioridad que el disco, y verifica que el swap en disco no esté en un dispositivo contendido.
3) Síntoma: “Habilitamos zram y ahora los caches están peores y el rendimiento empeoró”
Causa raíz: zram demasiado grande; roba RAM del page cache y las páginas anónimas calientes, provocando más IO y fallos.
Solución: reduce el tamaño de zram; trátalo como un pequeño buffer de emergencia, no como un segundo banco de RAM. Vuelve a probar con carga real.
4) Síntoma: el sistema ya no hace OOM, pero se vuelve inresponsive por minutos
Causa raíz: thrashing: el working set supera significativamente la RAM. zram hace el fallo más lento y más doloroso.
Solución: establece límites, reduce uso de memoria o añade RAM. Considera mantener un pequeño swap en disco con zswap (o no usar swap) según los SLOs; decide si un OOM rápido es preferible a stalls largos.
5) Síntoma: zswap habilitado, pero las escrituras de swap siguen siendo intensas
Causa raíz: el pool de zswap se satura rápido; ratios de compresión pobres (muchos rejects); o el backend de swap se usa directamente por temas de política/prioridad.
Solución: inspecciona los contadores debug de zswap; aumenta el cap del pool moderadamente o ajusta algoritmo; verifica dispositivos y prioridades de swap; arregla el crecimiento de memoria subyacente.
6) Síntoma: cargas en contenedores hacen OOM dentro de cgroups aunque el host tiene memoria libre
Causa raíz: memory.max de cgroup está demasiado bajo; el comportamiento de swap difiere dentro del cgroup; el zram/zswap a nivel host no arreglará un límite malo.
Solución: ajusta límites de cgroup, fija presupuestos sensatos por servicio y monitoriza PSI por cgroup si es posible. No uses compresión global de swap como vendaje para cuotas mal definidas.
7) Síntoma: “Se usa swap aunque hay RAM ‘libre’”
Causa raíz: malentendido de los reportes de memoria de Linux; “free” vs “available”, dinámica del page cache y reclaim proactivo.
Solución: usa free -h y céntrate en “available”, usa PSI para confirmar presión real. No desactives swap a la ligera porque “swap usado != malo.”
8) Síntoma: problemas de suspend/resume o hibernación en portátiles después de habilitar zram
Causa raíz: la hibernación requiere un respaldo de swap lo suficientemente grande para escribir la imagen de RAM; zram no es adecuado como único objetivo de hibernación.
Solución: mantiene una partición/archivo de swap en disco dimensionado para hibernación; usa zram como swap adicional con mayor prioridad, no como el único swap.
Listas de verificación / plan paso a paso
Checklist A: Decide qué desplegar (por clase de nodo)
- Clasifica el nodo: portátil, VM, base de datos, runner de CI, host de contenedores, caja edge.
- Define la preferencia de fallo: OOM rápido vs desaceleración elegante. Para servicios críticos de latencia, un fallo rápido suele ser más seguro.
- Comprueba margen de CPU: si la CPU está rutinariamente >70% en pico, el coste de compresión puede perjudicar.
- Comprueba la calidad del backend de swap: SSD/NVMe está bien; almacenamiento en red lento o discos contendidos no lo están.
- Elige una estrategia: zswap-only para la mayoría de servidores; zram-only para edge sin disco/lento; escalonado para entornos con almacenamiento ruidoso.
Checklist B: Línea base segura para un servidor Debian 13 (zswap-first)
- Asegúrate de tener un dispositivo de swap real (swapfile o partición) dimensionado a tu política.
- Habilita zswap y empieza con un algoritmo rápido.
- Configura alertas en PSI de memoria “full” y tasa de swap-in.
- Haz pruebas de carga con concurrencia realista y vigila latencias cola, no solo throughput.
- Solo entonces considera añadir un pequeño tier zram si el swap en disco sigue siendo el cuello de botella.
Checklist C: Swap en capas (zram + disco) sin sabotearte
- Crea/habilita swap zram con prioridad más alta que el swap en disco.
- Mantén el swap en disco como respaldo con prioridad más baja.
- Limita el tamaño de zram a una fracción conservadora (10–25% de RAM para servidores).
- Usa LZ4 a menos que tengas evidencia medida en contrario.
- Monitoriza: llenado de zram, ratio de compresión, tasas de swap-in/out y CPU.
Checklist D: Respuesta a incidentes cuando llega la presión de memoria
- Comprueba PSI (memory). Si “full” está elevado, trátalo como severidad.
- Comprueba la tasa de swap-in y fallos mayores. Confirma paginación activa.
- Revisa await/util del disco. Si está saturado, el IO es parte del problema.
- Encuentra al mayor ofensordo de memoria y decide: reiniciar, limitar o escalar.
- Post-incidente: arregla la regresión de memoria y añade un guardarraíl (límite, presupuesto o alerta).
Preguntas frecuentes
1) ¿Debo usar zram o zswap en Debian 13?
Para la mayoría de servidores: zswap con un backend de swap real. Para dispositivos pequeños/edge: zram puede ser excelente. Para almacenamiento ruidoso: escalonado puede ser excelente si las prioridades son correctas.
2) ¿Puedo ejecutar zram y zswap juntos?
Sí, pero con deliberación. zswap cachea páginas destinadas a dispositivos de swap; si uno de esos dispositivos de swap es zram, puedes acabar comprimiendo “delante de” un dispositivo ya comprimido. Eso puede ser overhead redundante.
El patrón escalonado común es zram + swap en disco, no zswap + zram, a menos que hayas medido un beneficio real.
3) ¿La compresión de swap evita el OOM killer?
Puede retrasar el OOM al aumentar la capacidad efectiva para páginas frías/compresibles. No elimina el OOM si el conjunto de trabajo sigue creciendo.
A veces retrasar el OOM es malo: tienes minutos de timeouts en lugar de un fallo rápido y reinicio.
4) ¿Qué algoritmo de compresión debería elegir?
Empieza con LZ4 para servidores. Considera ZSTD solo después de medir el margen de CPU y probar que el mejor ratio reduce el swap en disco suficiente para mejorar latencias cola.
5) ¿Cuál es un tamaño sensato para zram?
Servidores: a menudo 10–25% de la RAM cuando se usa como capa rápida. Escritorios: 25–50% puede funcionar bien.
Si lo dimensionas “igual a la RAM” y lo dejas así, estás construyendo un generador de outages en cámara lenta.
6) ¿Por qué se usa swap cuando hay memoria “libre”?
Porque “free” no es “available”, y Linux usa memoria agresivamente para caches. Además, el kernel puede swapear páginas anónimas frías para preservar cache.
Mira “available” en free -h y usa PSI para confirmar stalls reales.
7) ¿Cómo sé si zswap realmente está ayudando?
Busca menores tasas de escritura a disco durante presión de memoria, menor IO wait y latencias de cola estables. En estadísticas de zswap, quieres un número saludable de páginas almacenadas y tasas manejables de writeback.
Si el pool se satura y las páginas escritas aumentan, solo estás posponiendo el dolor en disco.
8) ¿El swap es malo para bases de datos como PostgreSQL?
El swap no planificado es malo para bases de datos sensibles a latencia. Pero una pequeña cantidad de swap con zswap puede prevenir OOM catastrófico y reducir tormentas de IO.
La solución real es un dimensionado correcto de memoria y evitar sobrecommit; zswap es un cinturón de seguridad, no un motor nuevo.
9) ¿zram reducirá el desgaste del SSD?
Sí, si reemplaza o reduce escrituras de swap a disco. zswap también ayuda absorbiendo swap-outs en RAM y escribiendo de vuelta menos.
Pero si estás thrasheando fuerte, todavía puedes escribir en disco (evicción de zswap) y además quemar CPU.
10) ¿Por qué habilitar zram volvió el sistema más lento incluso sin mucho swapping?
Si zram está sobredimensionado, consume RAM para sus propios metadatos y compite con el page cache. El sistema puede reclamar más agresivamente o tener menor tasa de aciertos de cache, provocando más IO.
Dimensiona de forma conservadora y verifica con pruebas de carga.
Conclusión: siguientes pasos que puedes tomar hoy
Si ejecutas Debian 13 en producción, trata zram/zswap como cualquier otra característica de rendimiento: apuesta por entrar con intención, mide continuamente y revierte cuando te engañe.
La buena noticia es que no necesitas gestas heroicas. Necesitas un plan.
- Elige una política por defecto por clase de nodo (zswap-only es la ganadora aburrida para muchos servidores).
- Añade visibilidad: PSI de memoria, swap-in/out, await/util del disco y estadísticas de zram/zswap.
- Ejecuta una prueba de presión que refleje la realidad: concurrencia pico, jobs en segundo plano y vecinos ruidosos incluidos.
- Define tu preferencia de fallo: OOM rápido vs thrash lento, y alinea las configuraciones de swap/compresión a ello.
- Arregla la causa raíz tras el incidente: presupuestos de memoria, límites y dimensionado. La compresión no es un plan de capacidad.
El kernel hará lo posible por mantener tu sistema vivo. Tu trabajo es asegurarte de que “vivo” siga significando “útil”.