--- title: "Cómo aumentar ulimit y limits.conf en Ubuntu 24.04" description: "Diagnostica errores Too many open files y sube los límites de archivos abiertos y procesos en Ubuntu 24.04 con ulimit, limits.conf y LimitNOFILE de systemd." category: "Optimización de Rendimiento" language: es source: https://cubepath.com/es/docs/optimización-de-rendimiento/optimizacion-de-limites-del-sistema-ulimit-limits-conf updated: 2026-09-25 --- # Cómo aumentar ulimit y limits.conf en Ubuntu 24.04 Linux limita los recursos que puede usar cada proceso: cuántos archivos puede tener abiertos, cuántos procesos puede crear un usuario o cuánta memoria puede bloquear. Los valores por defecto son conservadores y un servidor web, una base de datos o un proxy con miles de conexiones simultáneas puede agotarlos, lo que produce errores como `Too many open files`. En este tutorial aprenderás a consultar estos límites en Ubuntu 24.04, a diagnosticar cuándo se alcanzan y a subirlos en el lugar correcto: `limits.conf` para las sesiones de usuario y systemd para los servicios. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Todo lo relativo a systemd es igual en Debian 12 y Rocky Linux 9. - Un usuario no root con privilegios `sudo`. - Opcional: un servicio como Nginx para seguir el ejemplo del paso 5. ## Conceptos básicos: límites blandos y duros Cada límite tiene dos valores: - **Blando (soft)**: el que se aplica realmente al proceso. El propio proceso puede subirlo hasta el límite duro. - **Duro (hard)**: el techo. Solo root puede subirlo; un usuario normal únicamente puede bajarlo. Los límites se heredan de proceso padre a hijo, y quién los fija al principio depende de cómo arranca el proceso: | Cómo arranca el proceso | Quién fija sus límites | |---|---| | Sesión SSH o de consola | PAM, con `/etc/security/limits.conf` y `/etc/security/limits.d/` | | Servicio de systemd | La unidad del servicio (`LimitNOFILE=`, `LimitNPROC=`...) | | Contenedor Docker | El demonio de Docker o la opción `--ulimit` | Este es el error más común: `limits.conf` **no afecta a los servicios de systemd**. Si subes allí el límite de archivos de Nginx o MySQL y reinicias el servicio, no cambia nada. Los límites que más se ajustan son estos: | Recurso | Opción de `ulimit` | Nombre en `limits.conf` | Directiva de systemd | |---|---|---|---| | Archivos abiertos | `-n` | `nofile` | `LimitNOFILE=` | | Procesos por usuario | `-u` | `nproc` | `LimitNPROC=` | | Memoria bloqueada | `-l` | `memlock` | `LimitMEMLOCK=` | | Tamaño de volcados de memoria | `-c` | `core` | `LimitCORE=` | ## Paso 1: Consultar los límites actuales Muestra todos los límites blandos de tu shell: ```bash ulimit -a ``` Consulta el límite blando y el duro de archivos abiertos: ```bash ulimit -Sn ulimit -Hn ``` ```output 1024 524288 ``` Los límites de un proceso en ejecución se leen en `/proc/PID/limits`. Por ejemplo, para el servicio SSH: ```bash cat /proc/$(systemctl show -p MainPID --value ssh)/limits ``` ```output Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max processes 15413 15413 processes Max open files 1024 524288 files Max locked memory 8388608 8388608 bytes ... ``` ## Paso 2: Diagnosticar si se está alcanzando un límite El síntoma típico en los logs de una aplicación es uno de estos mensajes: ```text socket() failed (24: Too many open files) accept4() failed (24: Too many open files) fork: retry: Resource temporarily unavailable ``` El código 24 es `EMFILE`: el proceso ha llegado a su límite de archivos abiertos. Cada socket de red cuenta como un archivo, así que un servidor con muchas conexiones lo alcanza antes que ningún otro recurso. Cuenta los descriptores que tiene abiertos un proceso y compáralos con su límite. Sustituye `PID` por el identificador del proceso (lo obtienes con `pgrep -f nombre` o `systemctl show -p MainPID --value servicio`): ```bash sudo ls /proc/PID/fd | wc -l grep 'Max open files' /proc/PID/limits ``` Si el primer número se acerca al límite blando, has encontrado el problema. Para ver el total del sistema, consulta `/proc/sys/fs/file-nr`. Sus tres valores son descriptores asignados, libres (siempre 0 en kernels modernos) y el máximo del sistema: ```bash cat /proc/sys/fs/file-nr ``` ```output 2336 0 9223372036854775807 ``` En Ubuntu 24.04 el máximo global es prácticamente ilimitado, así que el cuello de botella siempre es el límite por proceso. ## Paso 3: Cambiar el límite en la sesión actual `ulimit` modifica los límites del shell actual y de los procesos que lance, y se pierde al cerrar la sesión. Es útil para probar. Sube el límite blando con `-S`; sin esa opción, bash cambia a la vez el blando y el duro: ```bash ulimit -Sn 65535 ulimit -Sn ``` ```output 65535 ``` Si intentas superar el límite duro sin ser root, obtendrás `ulimit: open files: cannot modify limit: Operation not permitted`. ## Paso 4: Hacer permanente el límite para usuarios con limits.conf Para las sesiones SSH y de consola, el módulo `pam_limits` aplica lo que haya en `/etc/security/limits.conf` y en los archivos de `/etc/security/limits.d/`. Comprueba que está activo para SSH: ```bash grep pam_limits /etc/pam.d/sshd ``` ```output session required pam_limits.so ``` En lugar de editar `limits.conf`, crea un archivo propio: ```bash sudo nano /etc/security/limits.d/90-nofile.conf ``` Cada línea tiene el formato `dominio tipo recurso valor`. El dominio puede ser un usuario, un grupo con `@` delante o `*` para todos: ```text # Usuario de la aplicación your_user soft nofile 65535 your_user hard nofile 65535 # Todos los miembros del grupo developers @developers soft nofile 65535 @developers hard nofile 65535 # El comodín * no se aplica a root: hay que nombrarlo aparte root soft nofile 65535 root hard nofile 65535 ``` Sustituye `your_user` por tu usuario. Los cambios se aplican en las sesiones nuevas, no hay que reiniciar nada. Abre una nueva conexión SSH y compruébalo: ```bash ulimit -Sn ulimit -Hn ``` ```output 65535 65535 ``` ## Paso 5: Subir el límite de un servicio de systemd Para los servicios, el límite se define en la unidad. No edites el archivo original en `/usr/lib/systemd/system/`, porque una actualización del paquete lo sobrescribiría. Crea un archivo de ajustes (drop-in) con `systemctl edit`. Este ejemplo usa Nginx: ```bash sudo systemctl edit nginx ``` Se abre un editor. Escribe el bloque entre los comentarios que indican dónde añadir contenido: ```ini [Service] LimitNOFILE=65535 ``` Al guardar, systemd crea `/etc/systemd/system/nginx.service.d/override.conf` y recarga la configuración. Reinicia el servicio para que el nuevo límite se aplique: ```bash sudo systemctl restart nginx ``` Verifica el límite que systemd aplica y el que tiene realmente el proceso: ```bash systemctl show nginx -p LimitNOFILE cat /proc/$(systemctl show -p MainPID --value nginx)/limits | grep 'open files' ``` ```output LimitNOFILE=65535 Max open files 65535 65535 files ``` Algunas aplicaciones tienen además su propio ajuste. En Nginx, los procesos worker usan el valor de `worker_rlimit_nofile` en `/etc/nginx/nginx.conf`, y `worker_connections` debe quedar por debajo de él: ```nginx worker_rlimit_nofile 65535; events { worker_connections 16384; } ``` Comprueba la sintaxis y recarga Nginx: ```bash sudo nginx -t sudo systemctl reload nginx ``` > Nota: Un valor de `LimitNOFILE` muy alto (por ejemplo `infinity`) no es gratis: algunos programas recorren todos los descriptores posibles al arrancar o al crear procesos hijos y se vuelven lentos. Usa un valor holgado pero realista, como 65535 o 262144. ## Paso 6: Cambiar el valor por defecto de todos los servicios (opcional) Si varios servicios necesitan el mismo límite, puedes cambiar el valor por defecto del gestor de systemd en lugar de crear un drop-in para cada uno: ```bash sudo mkdir -p /etc/systemd/system.conf.d sudo nano /etc/systemd/system.conf.d/limits.conf ``` ```ini [Manager] DefaultLimitNOFILE=65535:524288 ``` El formato `blando:duro` mantiene el límite duro que Ubuntu ya usa por defecto. Aplica el cambio recargando el gestor y reinicia los servicios afectados: ```bash sudo systemctl daemon-reexec sudo systemctl restart nginx ``` Los servicios con su propio `LimitNOFILE=` siguen usando el suyo. ## Paso 7: Límite de procesos y TasksMax El error `fork: retry: Resource temporarily unavailable` puede venir de dos límites distintos: - **`nproc`**: número máximo de procesos e hilos del mismo usuario. Se ajusta igual que `nofile`, con `nproc` en `limits.d` o `LimitNPROC=` en la unidad. Por defecto ya es alto (unos 15000 en un servidor de 4 GB), así que rara vez es la causa. - **`TasksMax`**: límite de procesos e hilos de systemd por servicio, mediante cgroups. Es la causa habitual en servicios que crean muchos hilos, como bases de datos o aplicaciones Java. Consulta el límite de tareas de un servicio y cuántas usa. Sustituye `your_service` por su nombre: ```bash systemctl show your_service -p TasksMax -p TasksCurrent ``` ```output TasksMax=4618 TasksCurrent=187 ``` Si `TasksCurrent` se acerca a `TasksMax`, súbelo con `sudo systemctl edit your_service`: ```ini [Service] TasksMax=16384 ``` Después reinicia el servicio con `sudo systemctl restart your_service`. ## Solución de problemas **El límite no cambia al conectar por SSH.** Comprueba que no hay errores de sintaxis en `/etc/security/limits.d/`; `pam_limits` ignora las líneas que no entiende y lo registra en `sudo journalctl -t sshd`. Recuerda que el blando nunca puede superar al duro. **El límite no se aplica con `sudo -u` o `su`.** Los límites dependen de la configuración PAM de cada herramienta. Para procesos permanentes, usa un servicio de systemd con `LimitNOFILE=` en lugar de lanzarlos desde una sesión. **El servicio sigue con 1024 después del drop-in.** Revisa que el archivo tiene la cabecera `[Service]`, ejecuta `systemctl cat nombre_servicio` para ver la configuración combinada y reinicia el servicio, no basta con `reload`. **Un contenedor Docker muestra otro límite.** Los contenedores heredan los límites del demonio de Docker. Fíjalos por contenedor con `docker run --ulimit nofile=65535:65535` o con la clave `ulimits` en Docker Compose. ## Conclusión Ya sabes leer los límites de cualquier proceso, detectar cuándo se agotan y subirlos donde corresponde: `/etc/security/limits.d/` para las sesiones de usuario y `LimitNOFILE` o `TasksMax` en systemd para los servicios. Como siguientes pasos, revisa los ajustes propios de tus aplicaciones (como `worker_connections` en Nginx o `max_connections` en MySQL), ajusta los parámetros del kernel con sysctl y monitoriza el número de descriptores abiertos de tus servicios críticos.