--- title: "Configurar swap y ajustar la memoria en Ubuntu 24.04" description: "Crea un archivo de swap, ajusta swappiness y la caché de páginas, activa zswap y protege tus servicios del OOM killer con systemd en un servidor Ubuntu 24.04." category: "Rendimiento y Benchmarking" language: es source: https://cubepath.com/es/docs/rendimiento-y-benchmarking/gestion-de-memoria-y-optimizacion-de-swap updated: 2026-09-25 --- # Configurar swap y ajustar la memoria en Ubuntu 24.04 Cuando un servidor Linux se queda sin memoria, puede ocurrir una de dos cosas: que empiece a usar swap de forma intensiva y todo se vuelva lento, o que el OOM killer del kernel termine un proceso, a menudo el más importante. Ninguna es buena, pero ambas se pueden controlar. En este tutorial diagnosticarás el uso de memoria de un servidor Ubuntu 24.04, crearás un archivo de swap, ajustarás cuándo y cómo el kernel lo usa, activarás zswap para comprimir páginas en RAM y decidirás con systemd qué servicios se sacrifican primero si la memoria se agota. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Espacio libre en disco para el archivo de swap (entre 1 y 4 GB en la mayoría de casos). ## Paso 1: Diagnosticar el uso de memoria Empieza por una foto del estado actual: ```bash free -h ``` ```output total used free shared buff/cache available Mem: 3.8Gi 1.9Gi 312Mi 48Mi 1.8Gi 1.7Gi Swap: 0B 0B 0B ``` La columna importante es `available`, no `free`. Linux usa la memoria libre como caché de archivos (`buff/cache`) y la devuelve cuando un proceso la pide, así que un `free` bajo no es un problema. Este servidor tiene 1,7 GB disponibles y no tiene swap, algo habitual en imágenes cloud de Ubuntu. Para saber si la memoria es realmente un cuello de botella, consulta la información de presión (PSI), que mide el porcentaje de tiempo que los procesos pasan esperando por memoria: ```bash cat /proc/pressure/memory ``` ```output some avg10=0.00 avg60=0.00 avg300=0.00 total=10432 full avg10=0.00 avg60=0.00 avg300=0.00 total=2211 ``` `some` indica el tiempo en que al menos un proceso estuvo bloqueado esperando memoria, y `full` el tiempo en que todos lo estuvieron. Los valores `avg10`, `avg60` y `avg300` son porcentajes de los últimos 10, 60 y 300 segundos. Si `some avg60` supera con frecuencia el 5-10 %, al servidor le falta memoria de verdad y ningún ajuste lo resolverá: toca reducir consumo o ampliar RAM. Por último, comprueba si el OOM killer ya ha actuado alguna vez: ```bash journalctl -k -g 'Out of memory' --no-pager ``` ```output sep 20 03:12:44 web01 kernel: Out of memory: Killed process 20417 (php-fpm8.3) total-vm:812344kB, anon-rss:402112kB, ... ``` Si no aparece nada, verás `-- No entries --`. ## Paso 2: Crear un archivo de swap Un poco de swap da margen al kernel para sacar de la RAM páginas que casi nunca se usan (memoria de arranque de servicios, librerías cargadas y olvidadas) y deja más espacio para la caché y los procesos activos. Además, convierte un pico puntual de memoria en una ralentización temporal en lugar de un proceso muerto. Como referencia de tamaño: | RAM del servidor | Swap recomendada | |---|---| | Hasta 2 GB | Igual a la RAM | | 2 a 8 GB | 2 a 4 GB | | Más de 8 GB | 4 GB, o más si usas hibernación (no aplica a servidores) | Comprueba que no hay swap activa: ```bash swapon --show ``` Si el comando no devuelve nada, crea un archivo de 2 GB. `fallocate` reserva el espacio al instante en ext4 y XFS: ```bash sudo fallocate -l 2G /swapfile ``` > Nota: si la raíz está en Btrfs, `fallocate` no sirve para swap. Usa en su lugar `sudo btrfs filesystem mkswapfile --size 2g /swapfile`, que crea el archivo con los atributos que Btrfs necesita, y continúa con `swapon`. Restringe los permisos para que solo root pueda leerlo, ya que contendrá fragmentos de memoria de los procesos: ```bash sudo chmod 600 /swapfile ``` Formatea el archivo como swap y actívalo: ```bash sudo mkswap /swapfile sudo swapon /swapfile ``` Verifica que el kernel lo está usando: ```bash swapon --show ``` ```output NAME TYPE SIZE USED PRIO /swapfile file 2G 0B -2 ``` Para que se active en cada arranque, añádelo a `/etc/fstab`: ```bash echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab ``` Comprueba la entrada sin reiniciar: desactiva la swap y vuelve a activar todo lo que esté en `fstab`. Si la línea tuviera un error, `swapon -a` lo mostraría: ```bash sudo swapoff /swapfile sudo swapon -a swapon --show ``` ## Paso 3: Ajustar swappiness y la caché de archivos `vm.swappiness` controla cuánto prefiere el kernel mover memoria de procesos a swap frente a descartar caché de archivos. El valor por defecto es 60. En un servidor con swap en SSD, un valor de 10 mantiene los procesos en RAM y solo usa swap cuando la memoria está realmente justa, sin desactivarla del todo. `vm.vfs_cache_pressure` controla la tendencia a liberar la caché de metadatos del sistema de archivos (dentries e inodos). El valor por defecto es 100. Bajarlo a 50 ayuda en servidores que recorren muchos archivos pequeños, como un servidor web con miles de archivos estáticos o un servidor de correo. Consulta los valores actuales: ```bash sysctl vm.swappiness vm.vfs_cache_pressure ``` ```output vm.swappiness = 60 vm.vfs_cache_pressure = 100 ``` Guarda los nuevos valores en un archivo propio para que persistan: ```bash sudo nano /etc/sysctl.d/99-memoria.conf ``` ```ini vm.swappiness = 10 vm.vfs_cache_pressure = 50 ``` Aplica el archivo y verifica: ```bash sudo sysctl -p /etc/sysctl.d/99-memoria.conf ``` ```output vm.swappiness = 10 vm.vfs_cache_pressure = 50 ``` > Nota: `vm.swappiness = 0` no desactiva la swap, pero hace que el kernel solo la use en el último momento, cuando ya está cerca del OOM. Casi nunca es lo que quieres; si no quieres swap, no la crees. ### Escrituras pendientes: vm.dirty_ratio Los parámetros `vm.dirty_background_ratio` (10 % por defecto) y `vm.dirty_ratio` (20 %) marcan cuánta memoria pueden ocupar los datos escritos pero aún no volcados a disco antes de que el kernel empiece a volcarlos en segundo plano, y antes de que bloquee a los procesos que escriben. En servidores con mucha RAM, un 20 % pueden ser decenas de gigabytes pendientes, y el volcado provoca pausas largas. En ese caso, fija límites en bytes, que sustituyen a los porcentajes. Añádelos al mismo archivo `/etc/sysctl.d/99-memoria.conf`: ```ini vm.dirty_background_bytes = 268435456 vm.dirty_bytes = 1073741824 ``` Con esto el volcado empieza con 256 MB pendientes y los procesos se bloquean a partir de 1 GB. En servidores pequeños (menos de 8 GB) los valores por defecto suelen estar bien y puedes omitir este bloque. ## Paso 4: Activar zswap zswap es una caché comprimida en RAM que se sitúa delante de la swap. Cuando el kernel decide llevar una página a swap, primero la comprime y la guarda en memoria; solo si esa caché se llena, escribe en disco. Con ratios de compresión típicos de 2:1 o 3:1, reduce mucho las E/S de swap a cambio de algo de CPU. Necesita una swap real detrás, que ya creaste en el paso 2. Comprueba si está activo, qué compresor usa y qué porcentaje máximo de la RAM puede ocupar: ```bash grep . /sys/module/zswap/parameters/{enabled,compressor,max_pool_percent} ``` ```output /sys/module/zswap/parameters/enabled:N /sys/module/zswap/parameters/compressor:lzo-rle /sys/module/zswap/parameters/max_pool_percent:20 ``` Para activarlo de forma persistente, añade los parámetros a la línea de arranque del kernel. Edita la configuración de GRUB: ```bash sudo nano /etc/default/grub ``` Añade la opción de zswap al final del valor de `GRUB_CMDLINE_LINUX_DEFAULT`, conservando lo que ya tenga: ```ini GRUB_CMDLINE_LINUX_DEFAULT="zswap.enabled=1" ``` Se mantiene el compresor por defecto del kernel, que está integrado en él y por tanto disponible desde el arranque. Regenera la configuración de GRUB: ```bash sudo update-grub ``` > Nota: en algunas imágenes cloud de Ubuntu, la línea de arranque se sobrescribe desde `/etc/default/grub.d/50-cloudimg-settings.cfg`. Si tras reiniciar zswap sigue desactivado, añade la opción en ese archivo en lugar de en `/etc/default/grub`. Para activarlo ahora sin reiniciar, escribe en su parámetro `enabled`: ```bash echo 1 | sudo tee /sys/module/zswap/parameters/enabled ``` Verifica el estado. Tras un tiempo con presión de memoria, las líneas `Zswap` (memoria usada por la caché comprimida) y `Zswapped` (datos originales que representa) de `/proc/meminfo` mostrarán valores distintos de cero: ```bash cat /sys/module/zswap/parameters/enabled grep -E '^(Zswap|Zswapped)' /proc/meminfo ``` ```output Y Zswap: 41220 kB Zswapped: 118904 kB ``` ## Paso 5: Controlar el OOM killer con systemd Cuando la memoria se agota del todo, el OOM killer elige un proceso según su puntuación `oom_score`, que depende sobre todo de cuánta memoria usa. Eso significa que suele morir la base de datos, justo el proceso que menos quieres perder. Puedes influir en la elección con `OOMScoreAdjust=` en la unidad de systemd: los valores van de -1000 (nunca matar) a 1000 (matar primero). Protege la base de datos con un override. El ejemplo usa MySQL; sustituye el nombre por el de tu servicio: ```bash sudo systemctl edit mysql ``` Añade entre las líneas de comentario del editor: ```ini [Service] OOMScoreAdjust=-500 ``` Reinicia el servicio y comprueba el valor aplicado al proceso: ```bash sudo systemctl restart mysql cat /proc/"$(pidof mysqld)"/oom_score_adj ``` ```output -500 ``` Evita usar -1000 salvo en casos muy justificados: si el proceso protegido es el que tiene la fuga de memoria, el kernel matará todo lo demás, incluido SSH, antes de tocarlo. La otra cara es limitar a los servicios que pueden desbocarse, como un pool de PHP-FPM. Con `MemoryHigh=` el kernel empieza a reclamar memoria agresivamente de ese servicio al superar el umbral, y con `MemoryMax=` el OOM actúa solo dentro del servicio, sin afectar al resto del servidor: ```bash sudo systemctl edit php8.3-fpm ``` ```ini [Service] MemoryHigh=1536M MemoryMax=2G ``` ```bash sudo systemctl restart php8.3-fpm systemctl show php8.3-fpm -p MemoryHigh -p MemoryMax -p MemoryCurrent ``` ```output MemoryHigh=1610612736 MemoryMax=2147483648 MemoryCurrent=312475648 ``` Con esto, si PHP-FPM consume de más, será él quien sufra el OOM y systemd lo reiniciará según su política `Restart=`, mientras la base de datos sigue en pie. ## Paso 6: Vigilar la swap bajo carga Que haya swap usada no es un problema en sí; lo es que el sistema esté leyendo y escribiendo swap continuamente. `vmstat` lo muestra en las columnas `si` (KB/s leídos de swap) y `so` (KB/s escritos a swap): ```bash vmstat 5 ``` ```output 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 84120 298412 61220 1712400 0 0 3 41 512 880 6 2 91 1 0 2 0 84120 297980 61220 1712452 0 0 0 12 498 861 5 1 94 0 0 ``` Si `si` y `so` se mantienen en cero o casi, la swap está haciendo su trabajo: guarda páginas frías. Si ambas columnas muestran actividad constante junto con valores altos en `wa` (CPU esperando E/S) y en la presión `some` de PSI, el servidor está en thrashing: necesita más RAM o menos carga. Para saber qué procesos tienen memoria en swap: ```bash sudo grep -H VmSwap /proc/[0-9]*/status | sort -k2 -n -r | head -n 5 ``` ```output /proc/20417/status:VmSwap: 41280 kB /proc/1123/status:VmSwap: 12044 kB /proc/988/status:VmSwap: 3920 kB ``` Identifica el proceso con `ps -p 20417 -o comm=`. ## Solución de problemas **`swapon: /swapfile: insecure permissions 0644, 0600 suggested`**: el archivo tiene permisos demasiado abiertos. Ejecuta `sudo chmod 600 /swapfile`. **`swapon: /swapfile: swapon failed: Invalid argument`**: el sistema de archivos no admite archivos de swap creados con `fallocate` (Btrfs, algunos sistemas en red). Borra el archivo y créalo con el método de tu sistema de archivos, o con `sudo dd if=/dev/zero of=/swapfile bs=1M count=2048` en ext4 si `fallocate` no está disponible. **El OOM killer sigue matando la base de datos**: comprueba con `systemctl cat mysql` que el override está presente, y recuerda que `OOMScoreAdjust` solo ajusta la puntuación: si la base de datos es con diferencia el proceso más grande, puede seguir siendo elegida. Reduce su consumo (por ejemplo `innodb_buffer_pool_size`) o limita a los demás servicios con `MemoryMax`. ## Conclusión Has diagnosticado la memoria del servidor con `free` y PSI, añadido un archivo de swap persistente, ajustado `swappiness`, la caché de archivos y las escrituras pendientes, activado zswap y establecido con systemd qué servicios se protegen y cuáles se limitan. El resultado es un servidor que absorbe picos de memoria con una ralentización moderada en lugar de perder procesos críticos. Como siguientes pasos, puedes configurar alertas sobre la presión de memoria PSI en tu sistema de monitorización, revisar la configuración de memoria de tu base de datos o ajustar el programador de E/S del disco donde reside la swap.