Introducción: por qué tu servidor duerme cuando debería estar trabajando
\n\nImagina: un usuario hace clic en el botón "Enviar informe" y la página se congela durante 30 segundos. El servidor genera un PDF, comprime imágenes y envía un correo electrónico, todo de forma síncrona. ¿Te suena familiar? Si es así, has caído en la trampa del código bloqueante.
\n\nEn este artículo, analizaremos cómo las colas y tareas en segundo plano con TypeScript resuelven este problema. Aprenderás a trasladar el trabajo pesado a procesos en segundo plano sin perder el control sobre los errores y la escalabilidad. El material está escrito para desarrolladores que ya conocen Node.js y quieren llevar su proyecto al siguiente nivel.
\n\nHablaremos sobre las bibliotecas Bull y BullMQ, tocaremos RabbitMQ y mostraremos ejemplos reales de código en TypeScript. ¡Allá vamos!
¿Qué es una cola de tareas y para qué sirve?
\n\nUna cola de tareas (task queue) es un mecanismo que separa la solicitud del usuario de su ejecución. En lugar de procesar la operación directamente en el manejador HTTP, enviamos la tarea a una cola, y un worker en segundo plano la recoge y la ejecuta de forma asíncrona.
\n\nEscenarios de uso típicos
\n- \n
- Envío de correos electrónicos y notificaciones push \n
- Generación de PDF, imágenes, videos \n
- Análisis de datos y web scraping \n
- Procesamiento de pedidos en tiendas en línea \n
- Cálculos masivos e informes \n
Sin colas, tu aplicación corre el riesgo de caerse bajo carga. Con ellas, obtienes tolerancia a fallos (si un worker falla, la tarea no se pierde) y escalabilidad (puedes ejecutar 10 workers en lugar de uno).
\n\nBull y BullMQ: potentes colas para Node.js
\n\nBull es la biblioteca más popular para trabajar con colas en el ecosistema Node.js. Está basada en Redis y es compatible con TypeScript de forma nativa. BullMQ es su sucesor, más moderno, con soporte para sandboxes (procesos aislados) y gestión avanzada.
\n\nInstalación y configuración básica
\nnpm install bullmq ioredis\nnpm install -D @types/bull\n\nCreemos una cola y un worker en TypeScript:
\n\n// queue.ts\nimport { Queue } from 'bullmq';\n\nconst connection = {\n host: 'localhost',\n port: 6379,\n};\n\nexport const emailQueue = new Queue('email', { connection });\n\n// worker.ts\nimport { Worker } from 'bullmq';\nimport { sendEmail } from './emailService';\n\nconst worker = new Worker('email', async job => {\n const { to, subject, body } = job.data;\n await sendEmail(to, subject, body);\n console.log(`Email sent to ${to}`);\n}, { connection });\n\nworker.on('completed', job => {\n console.log(`Job ${job.id} completed`);\n});\n\nworker.on('failed', (job, err) => {\n console.error(`Job ${job.id} failed: ${err.message}`);\n});\n\nAhora, desde cualquier parte de la aplicación, podemos añadir una tarea:
\n\nimport { emailQueue } from './queue';\n\nawait emailQueue.add('send-welcome', {\n to: 'user@example.com',\n subject: '¡Bienvenido!',\n body: 'Gracias por registrarte...'\n});\n\nSencillo, ¿verdad? Pero esto es solo el comienzo. BullMQ ofrece muchas más posibilidades.
\n\nFuncionalidades avanzadas de BullMQ
\n- \n
- Reintentos — si una tarea falla, se puede reiniciar automáticamente después de N segundos. \n
- Retraso en la ejecución — posponer una tarea para un momento específico. \n
- Prioridades — las tareas urgentes se procesan antes. \n
- Eventos — puedes suscribirte al progreso, finalización, errores. \n
- Sandboxes — ejecución de código en un proceso aislado (seguridad + limpieza). \n
Ejemplo con reintentos y retraso:
\n\nawait emailQueue.add('send-invoice', {\n invoiceId: 123,\n email: 'client@example.com'\n}, {\n attempts: 5,\n backoff: { type: 'expon