"El aula va lenta" es la queja que más destruye la confianza de docentes y alumnos en una plataforma nueva. Y casi nunca es culpa de Moodle: es una instalación por defecto que nunca se ajustó.
Este artículo ordena los ajustes por impacto, de la medición a la configuración. Los valores son puntos de partida: cada servidor se mide y se afina.
1. Mide antes de tocar
Sin medir, optimizas a ciegas. Tres comprobaciones rápidas:
- Tiempo hasta el primer byte (TTFB) de la página de inicio y de un curso, desde las herramientas de desarrollo del navegador. Si es alto, el problema es del servidor; si es bajo pero la página tarda, es del front (tema, imágenes, JavaScript).
- El informe Visión general del rendimiento en Administración del sitio > Informes, que señala ajustes mejorables.
- El registro de consultas lentas de la base de datos durante una hora de uso real.
Si vas a abrir el aula a muchos alumnos a la vez (por ejemplo, un examen), Moodle incluye en Administración > Desarrollo generadores de cursos de prueba y de plan de JMeter para simular carga.
2. OPcache de PHP: lo primero, siempre
OPcache guarda el código PHP ya compilado. Moodle tiene miles de ficheros PHP, así que sin OPcache bien dimensionado se recompilan una y otra vez.
; /etc/php/8.x/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
Tras cada actualización de Moodle, reinicia PHP-FPM para vaciar la caché.
3. PHP-FPM dimensionado para tu memoria
Con pocos procesos, los alumnos hacen cola. Con demasiados, el servidor se queda sin RAM y se va a swap, que es peor. La fórmula básica:
pm.max_children ≈ memoria disponible para PHP / memoria media por proceso
Ejemplo ilustrativo: en un servidor con 8 GB, si reservas 2 GB para sistema y base de datos y cada proceso PHP ocupa unos 100 MB, queda margen para unos 60 procesos. Mide el consumo real de tus procesos antes de fijar el número.
pm = dynamic
pm.max_children = 60
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
4. Sesiones y caché en Redis
Por defecto, Moodle guarda las sesiones en la base de datos y la caché en ficheros. Mover ambas a Redis descarga la base de datos y acelera cada página. En config.php:
$CFG->session_handler_class = '\core\session\redis';
$CFG->session_redis_host = '127.0.0.1';
$CFG->session_redis_port = 6379;
$CFG->session_redis_database = 0;
$CFG->session_redis_prefix = 'aula_sess_';
$CFG->session_redis_acquire_lock_timeout = 120;
$CFG->session_redis_lock_expire = 7200;
// Caché local en disco rápido, fuera de moodledata compartido
$CFG->localcachedir = '/var/cache/moodle';
Las cachés de aplicación (MUC) se asignan a Redis desde Administración > Plugins > Caché > Configuración, creando una instancia de almacén Redis y mapeándola.
5. Base de datos con memoria suficiente
Una base de datos con valores por defecto vive con muy poca memoria. En MariaDB, el parámetro con más efecto es innodb_buffer_pool_size: que el conjunto de datos activo quepa en RAM. En PostgreSQL, shared_buffers y effective_cache_size. Cualquiera que sea la base de datos, empieza por el registro de consultas lentas: normalmente hay dos o tres culpables claras, a menudo ligadas a un plugin.
6. Servir ficheros sin pasar por PHP
Cada PDF o vídeo que se descarga a través de PHP ocupa un proceso entero mientras dura la descarga. Con nginx puedes delegar el envío:
# config.php
$CFG->xsendfile = 'X-Accel-Redirect';
$CFG->xsendfilealiases = array('/dataroot/' => $CFG->dataroot);
# nginx
location /dataroot/ {
internal;
alias /var/moodledata/;
}
El vídeo pesado, además, conviene que no salga del propio servidor del aula si el centro tiene mucho tráfico.
7. El cron, cada minuto
Moodle necesita que su cron se ejecute cada minuto. Si va cada cinco o cada hora, los avisos llegan tarde y las tareas programadas se acumulan.
* * * * * www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php > /dev/null
8. El front también cuenta
- Desactiva el modo diseñador de temas y asegúrate de que la caché de JavaScript está activa.
- Activa compresión gzip o brotli en nginx y caché de estáticos.
- Sube imágenes optimizadas, no fotos de 6 MB.
- Un tema recargado con muchos efectos y bloques en la portada puede costar más que cualquier ajuste de servidor.
- La depuración en producción debe estar en "Ninguno".
Orden de ataque recomendado
- Medir y localizar si el cuello es servidor, base de datos o front.
- OPcache, PHP-FPM y cron.
- Redis para sesiones y caché.
- Consultas lentas y memoria de la base de datos.
- Envío de ficheros y ajustes de front.
- Prueba de carga antes de un evento crítico.
Nuestro enfoque: cuando montamos un aula Moodle en Keappi, partimos de estos ajustes en lugar de dejarlos para un "ya lo optimizaremos". Si tu aula actual va lenta, cuéntanoslo y la revisamos contigo.