El usuario pulsa «Confirmar». La petición HTTP genera el PDF, habla con el SMTP, espera al proveedor de pago y, si hay suerte, responde en cuatro segundos. Si el SMTP se atasca, la página se queda en blanco y el pedido ha podido cobrarse. Las colas jobs segundo plano no son moda de arquitectura: son dejar de poner una bomba en el request.
No toda web lo necesita. Un corporativo que manda un formulario a un correo y ya, a menudo no. Una plataforma que emite entradas, genera documentos, sincroniza stock o dispara emails transaccionales en cada compra, sí. La pregunta no es «¿tenemos Redis?». Es qué trabajo no puede permitirse fallar en la cara del usuario.
Este artículo marca cuándo extraer el trabajo pesado en un desarrollo web a medida, qué implica reintentar, y qué no hace falta convertir en microservicio. El criterio que usamos en Truman cuando el monolito todavía aguanta —y cuando el request ya no.
Colas jobs segundo plano: qué problema resuelven de verdad
Una cola no es «más moderno». Es un sitio donde dejas un trabajo para que otro proceso lo haga después: enviar el correo, generar el PDF, llamar a un webhook, redimensionar una imagen, cerrar un lote. El request HTTP se limita a validar, persistir lo esencial y responder. El usuario no espera al SMTP.
Eso cambia tres cosas. Latencia: la página responde en el tiempo de tu base de datos, no en el del proveedor más lento. Resiliencia: si el mailer cae, el job queda y se reintenta. Capacidad: el pico de trabajo pesado no se come los procesos que sirven HTML. Sin eso, cada «mejora» de producto (un PDF más, un segundo email, un OCR) alarga el request hasta que un día revienta.
No sustituye a un buen hosting y caché. Una cola no arregla un TTFB malo ni un shared saturado. Extrae trabajo. Si el trabajo que sirve la página es el que está lento, el problema es otro.
Lo que no debería vivir en la petición HTTP
Hay una lista corta y aburrida. Si tu web hace dos o más de estas cosas dentro del controller, ya estás en zona de riesgo —aunque hoy el tráfico sea bajo.
| Trabajo | ¿En el request? | Por qué |
|---|---|---|
| Validar y guardar el pedido o el lead | Sí | Es el resultado que el usuario necesita ver ahora |
| Email transaccional (confirmación, entrada) | Cola | El SMTP falla. El usuario no tiene que esperar |
| PDF, entradas, facturas, zips | Cola | CPU y tiempo. Un timeout deja el cobro a medias |
| Llamadas a APIs lentas o inestables | Cola o asíncrono | Rate limits, caídas, 30 segundos de cortesía |
| Thumbnails, transcodificación, imports | Cola | No son una respuesta de página. Son un proceso |
| Un formulario que solo manda un correo | A veces request | Si falla, el usuario lo sabe y reenvía. Aún así, mejor cola |
La regla práctica: si el trabajo puede fallar por un tercero y el usuario ya ha hecho la acción irreversible (pagar, inscribirse, publicar), no puede vivir solo en el request. Tienes que poder repetirlo sin pedirle que pulse otra vez.
Jobs, reintentos y el día que falla de verdad
Encolar no basta. Un job sin reintento, sin tope y sin rastro es un try/catch aplazado. Hay que decidir: cuántas veces, con qué espera, qué se considera error transitorio (timeout, 429, 503) y qué es un error de datos que no se debe repetir (un email mal formado, un ID que no existe).
Idempotencia: el job se puede ejecutar dos veces sin duplicar el efecto. Un mail de «tu entrada» no se manda tres veces porque el worker se cayó a mitad. Un PDF no se genera en bucle. Eso se diseña con un identificador de trabajo y un estado: pendiente, hecho, fallido. Sin estado, cada reintento es una apuesta.
Aquí entra la observabilidad: un job fallido que no deja métrica ni traza es un fallo invisible. Necesitas ver el tamaño de la cola, el tiempo en cola, los reintentos y el error último. Sin eso, «tenemos workers» es una frase de README.
Si el proveedor de correo se cae una hora un sábado, ¿quién se entera y qué se reenvía solo?
Entradas, picos y el día del festival
En Klapper el producto es vender y entregar entradas. El clic de compra no puede esperar a renderizar un PDF y a que el SMTP conteste. El request confirma el pedido. El trabajo de generar, enviar y, si toca, notificar, va detrás. No es sofisticación: es no acoplar el cobro al mailer. Un festival o una sala no te espera a que el worker «ya se pondrá».
En Mallorca Live Festival la web aguanta informar, emocionar y vender en un calendario con picos. No todo pico pide una cola: el HTML se aguanta con caché, CDN y un hosting que no sea shared. La cola aparece cuando, encima del tráfico, hay trabajo de escritura —newsletter, imports de lineup, generación de assets, envíos—. Mezclar las dos conversaciones (servir páginas vs. procesar jobs) es el error. Una no sustituye a la otra.
Qué no meter en cola (aún) y qué no convertir en microservicio
Una cola es un proceso más que hay que operar: workers, supervisor, disco o Redis, alertas cuando la cola crece. Si tu web manda veinte correos al mes y genera un PDF de vez en cuando, un job síncrono bien acotado —con timeout y log— puede bastar. La complejidad se paga todos los días, no el día del diseño.
Tampoco hace falta un servicio aparte para cada job. El debate monolito frente a microservicios no se resuelve porque encoles el mail. Un worker en el mismo deploy, la misma base y la misma observabilidad es el sitio razonable para la mayoría de webs a medida. Extraer un microservicio de «emails» porque sí es otra factura de red, de contrato y de deploy. La cola es un patrón. El microservicio es una frontera de equipo. No las mezcles.
Cómo saber si tu web ya lo necesita
Tres señales honestas. Una: habéis tenido un incidente en el que el cobro o el alta existían y el email o el documento no. Dos: un proceso de admin (import, export, regenerar) tumba o ralentiza el front. Tres: estáis a punto de añadir el segundo o tercer tercero en el mismo request de checkout o de publish.
En Truman no vendemos una pila de colas. Vendemos un sistema que aguanta el oficio. A veces eso es un worker en el mismo monolito y tres jobs con nombre. A veces, más adelante, un bus. El orden es el de siempre: primero el producto que responde y deja rastro; la complejidad, cuando el request ya no puede con ella.
El request HTTP es un mostrador. No es una fábrica. Si detrás del clic estás imprimiendo, llamando a tres APIs y rezando al SMTP, no tienes un problema de «escalar». Tienes el trabajo en el sitio equivocado.
Antes de encolar (o de no hacerlo), verifica esto
- ¿Has listado qué hace cada request además de persistir el dato esencial?
- ¿El cobro o el alta sobreviven si el mail o el PDF fallan?
- ¿Los jobs son idempotentes y tienen un estado visible?
- ¿Hay reintento con tope y distinción entre error transitorio y de datos?
- ¿Alguien recibe una alerta si la cola crece o el worker se para?
- ¿Estás usando la cola para trabajo pesado, no para servir HTML más rápido?
- ¿El usuario ve un estado («enviando», «listo») cuando el trabajo va detrás?
- ¿Un worker en el mismo deploy basta, o de verdad necesitas otro servicio?
Preguntas frecuentes sobre colas y procesos en segundo plano
¿Cuándo una web a medida necesita colas y jobs?
Cuando el request hace trabajo que puede fallar por un tercero o tardar más de lo que un usuario espera: correos, PDFs, llamadas a APIs, imports. Si eso ocurre después de un pago o de un alta, ya no es opcional. Si tu web solo muestra páginas y un formulario simple, puede esperar.
¿Hace falta Redis o un microservicio para tener colas?
No por definición. Hace falta un sitio donde persistir el job y un proceso que lo consuma. Redis, una tabla o el sistema de colas del framework valen si se operan. El microservicio aparece cuando hay un equipo y un contrato que lo justifiquen. No cuando quieres «arquitectura moderna».
¿Qué es un job idempotente?
Uno que puedes ejecutar dos veces y el efecto de negocio ocurre una. No dos mails iguales, no dos cargos, no dos PDFs contradictorios. Se consigue con un identificador estable y un estado «ya hecho». Sin eso, el reintento es peligroso.
¿Las colas mejoran los Core Web Vitals?
Solo de forma indirecta: si dejas de hacer trabajo pesado en la petición que pinta la página, esa petición puede ser más corta. El LCP de la home no se arregla con workers. Se arregla con hosting, caché e imágenes. No uses la cola como parche de rendimiento de front.