Por Fran Navoz en Hosting, Nicalia, Productos y servicios
05 de agosto de 2026
Generar diez artículos con IA es fácil y rápido. Generar diez mil sin que el servidor se caiga por el camino es un problema técnico, no de prompts. Y ahí es donde casi todo el mundo tropieza.
Si automatizas contenido a volumen, seguramente ya conoces el patrón: la primera tanda va fina, y a las pocas horas el servidor se arrastra, MySQL se atasca y empiezan a llover errores 429 de la API. No es mala suerte ni un plugin defectuoso. Es que la automatización masiva rompe supuestos que tu hosting daba por buenos. Vamos a ver dónde se rompen y cómo evitarlo.
El origen de casi todos los desastres es la latencia variable de las APIs de IA. Una llamada puede tardar dos segundos o dos minutos según la carga del proveedor, y esa impredecibilidad rompe el supuesto sobre el que funciona el Cron de Linux de toda la vida: que una tarea termina antes de que empiece la siguiente.
Imagina un cronjob que se ejecuta cada 5 minutos. Un día la API se satura y tarda 6 minutos en responder. Cuando el primer proceso aún no ha terminado, arranca el segundo. A los 10 minutos hay tres corriendo a la vez. Cada uno consume su RAM, su CPU y sus conexiones a la base de datos, y el crecimiento es exponencial: en poco rato el servidor se queda sin memoria y el sistema mata procesos (OOM) o se reinicia. Un fallo que empezó siendo un retraso de un minuto acaba tirando la web entera.
La forma limpia de resolverlo es la exclusión mutua: garantizar que nunca haya dos ejecuciones a la vez. En Linux la herramienta es flock, que viene en el paquete estándar util-linux. Envuelves tu script con un archivo de bloqueo físico y el parámetro -n (no bloqueante), que aborta en silencio cualquier ejecución que intente solaparse:
*/5 * * * * /usr/bin/flock -n /tmp/generacion_contenido.lock \
/usr/bin/php /ruta/al/script_generacion.php
Si el proceso anterior sigue vivo, el nuevo no arranca y punto. Sin bola de nieve.
¿No tienes acceso a consola? En hosting compartido puedes replicar la idea en la capa de aplicación: una tabla de bloqueos con marcas de tiempo o PID. Guarda también el momento en que se tomó el bloqueo, para poder liberar los “huérfanos” si un script muere por OOM y deja la cerradura echada.
El segundo error clásico es usar MySQL como cola de tareas para miles de llamadas de IA. Funciona con cuatro tareas; con miles, se convierte en el cuello de botella de todo el sistema.
Para que varios workers no cojan la misma tarea, se suele recurrir a SELECT ... FOR UPDATE. Ese bloqueo de fila congela índices que el resto de la web necesita, así que el TTFB del frontend se dispara y los usuarios reales empiezan a ver timeouts. A eso se suma el desgaste por sondeo: workers preguntando a la base de datos cada pocos milisegundos “¿hay algo para mí?”, reconstruyendo planes de consulta una y otra vez sobre tablas casi vacías y quemando CPU para nada.
La diferencia de fondo es polling frente a push. En lugar de que el worker pregunte sin descanso (extracción activa), un bróker asíncrono como Redis o RabbitMQ le avisa solo cuando hay trabajo listo (notificación reactiva). El worker duerme tranquilo hasta que le llega el aviso, y la base de datos relacional se queda para lo que sabe hacer bien: guardar datos, no gestionar colas.
Un paso más allá está la ejecución persistente (herramientas como Temporal, o encolado durable tipo BullMQ o Celery). La idea es no repetir pasos caros: si tu flujo genera el texto, luego crea una imagen y la sube a S3, y el worker muere justo al subir la imagen, quieres reanudar desde ahí, no volver a pagar la llamada de texto que ya funcionó.

Todo esto aterriza en el CMS más usado del mundo a través de Action Scheduler, la biblioteca de colas que usan WooCommerce y muchos plugins de edición y enlazado masivo. Viene con topes conservadores de fábrica para no reventar hostings malos, y ahí está el problema cuando tú sí tienes un buen servidor.
Por defecto procesa en lotes de 25 acciones, con ejecuciones síncronas de 30 segundos y un solo hilo. Si tu hosting aguanta, puedes ampliarlo por código:
add_filter( 'action_scheduler_queue_runner_batch_size', fn() => 100 );
add_filter( 'action_scheduler_queue_runner_time_limit', fn() => 120 );
Lotes de 100 y hasta 120 segundos de margen cambian por completo el rendimiento en un servidor preparado.
–> Ojo, subir esto en un hosting flojo es la receta perfecta para el colapso, así que hazlo solo si tienes recursos que lo respalden.
Las migraciones masivas llenan wp_actionscheduler_actions con millones de registros, y llega un momento en que la propia tabla de tareas ralentiza MySQL. Cuando esto pasa (a veces con el temido MySQL server has gone away), un DELETE normal empeora las cosas: bloquea la tabla durante horas. El atajo de emergencia es guardar aparte lo que esté en estado pendiente y hacer un TRUNCATE, que vacía la tabla al instante:
TRUNCATE TABLE wp_actionscheduler_logs;
Haz una copia de seguridad antes de tocar nada y no truques la tabla de acciones sin extraer primero las pendientes, o perderás trabajo en cola.
Inserta el contenido de forma asíncrona al guardar en el backend (en el gancho save_post), nunca lo generes dinámicamente en tiempo de carga con hooks en caliente como the_content. Almacena el HTML ya calculado en la base de datos para servirlo en milisegundos. La diferencia para Google (y para el usuario) es abismal: una página que se pinta al instante frente a una que llama a una IA cada vez que alguien la abre.
Y cuando manejes objetos pesados (taxonomías enormes, listas de usuarios), cárgalos por fragmentos. El chunking (procesar en bloques de 100 a 500) evita desbordar la memoria RAM que PHP tiene asignada y te ahorra el clásico error de memoria agotada a mitad del proceso.
Los límites de un proveedor como OpenAI no se miden solo en llamadas por minuto (RPM). También cuentan los tokens por minuto (TPM) y las solicitudes diarias (RPD), y todo ello varía según tu historial de pagos: cuanto más llevas gastado, más alto es tu tier (del 1 al 5) y más margen tienes.
Cuando golpeas el límite, la API responde con un error HTTP 429. Si todos tus procesos reintentan exactamente al mismo tiempo, vuelves a chocar en el mismo milisegundo: es el efecto “estampida” (thundering herd). La solución es el retroceso exponencial con jitter: esperar cada vez un poco más y añadir una variación aleatoria para desincronizar los reintentos. Librerías como Tenacity lo hacen por ti y, de paso, evitan que el proveedor interprete tu ráfaga como un abuso.
Si el artículo no tiene que publicarse al segundo, no llames a la API en tiempo real. Agrupa las peticiones en un archivo .jsonl y mándalas a la Batch API de OpenAI. Las ventajas son claras:
A esto puedes sumar el prompt caching: si repites siempre las mismas instrucciones al principio del prompt (contexto, formato, tono), colócalas primero para que el proveedor las reutilice. El ahorro en tokens de entrada repetidos puede llegar a ser enorme, y de paso baja la latencia.
| Técnica | Qué te ahorra |
|---|---|
| Batch API | 50% del coste de tokens + no ocupa hilos locales |
| Prompt caching | Gran parte del coste de los tokens de entrada repetidos |
| Backoff con jitter | Reintentos que no se pisan ni disparan más 429 |
| Redis como cola | Libera a MySQL y baja el uso de CPU |
Todos estos problemas tienen un denominador común: necesitan una infraestructura que te deje trabajar a bajo nivel. Esto es lo que aporta el hosting WordPress de Nicalia en este escenario:
wp-cron es impreciso y síncrono, y degrada el rendimiento de la web. Con Cron de Linux integrado puedes usar flock -n como toca e impedir por completo el solapamiento de procesos.MySQL server has gone away.max_execution_time para procesamientos pesados.La automatización a escala no perdona una infraestructura floja. Nuestro hosting WordPress optimizado con Redis trae Cron de sistema, NVMe, Redis y acceso SSH, con soporte en español de administradores de sistemas que entienden estos cuellos de botella.
¿Tu proyecto es una tienda que genera fichas y descripciones con IA? El hosting para WooCommerce está afinado para que Action Scheduler y el catálogo convivan sin saturar el servidor.
flock -n (o una tabla de bloqueos si estás en compartido).save_post y se sirve como HTML precalculado.Casi siempre por solapamiento de procesos: la API tarda más de lo previsto, el Cron lanza una segunda ejecución antes de terminar la primera y el consumo se dispara hasta agotar la memoria. Se resuelve con exclusión mutua (flock).
Para volúmenes pequeños sí, pero a escala genera bloqueos de fila y sondeo constante que saturan el servidor. Una cola en memoria como Redis o RabbitMQ es mucho más eficiente.
Si no necesitas publicación inmediata, mucho: cuesta la mitad, te da límites de tokens más altos y no ocupa hilos de tu servidor durante la generación.
Las migraciones masivas acumulan millones de logs. Cuando degradan el rendimiento, un TRUNCATE (tras salvar las acciones pendientes) restaura MySQL al instante, sin los bloqueos largos de un DELETE.