Skip to main content

Qué es una cola

En una aplicación web hay operaciones que tardan varios segundos: enviar correos, redimensionar imágenes, llamar a APIs externas… Si las haces de forma síncrona durante la petición HTTP, el usuario tiene que esperar a que terminen para recibir la respuesta. Con las colas de Laravel puedes ejecutar esas operaciones en segundo plano de forma asíncrona. La petición responde inmediatamente y el trabajo real lo lleva a cabo un proceso worker aparte.
Las colas admiten varios backends (base de datos, Redis, Amazon SQS, etc.). En desarrollo puedes usar el driver sync para ejecutar los jobs al instante, sin cola.

Configuración de la cola

config/queue.php

Toda la configuración se centraliza en config/queue.php. La variable QUEUE_CONNECTION selecciona el driver.

Configuración en .env

Preparar el driver de base de datos

Si usas database, necesitas una tabla para almacenar los jobs. Los proyectos nuevos con Laravel 11+ incluyen la migración; si no, créala con:

Preparar el driver de Redis

Añade la configuración de Redis en config/database.php e instala el driver con Composer.

Overflow storage de SQS

Amazon SQS limita el tamaño de los mensajes. Si tus jobs generan payloads grandes, puedes configurar el excedente para guardarlo en la caché y enviar solo un puntero a SQS.
  • Con enabled, los payloads de más de 1 MB se guardan en el almacén de caché indicado.
  • Con always: true, se guardan siempre, sea cual sea su tamaño.
  • delete_after_processing elimina el payload al finalizar con éxito (por defecto true).
  • flush_on_clear: true vacía el store de overflow al ejecutar queue:clear. Como no queremos borrar el resto de la caché, úsalo con un store dedicado.

Crear la clase de job

Comando make:job

Genera el esqueleto con make:job.
Se crea app/Jobs/SendWelcomeEmail.php.

Estructura de la clase

Al implementar ShouldQueue, indicamos a Laravel que este job debe procesarse en cola. El trait Queueable aporta los métodos necesarios para operar sobre la cola.
Cuando pasas un modelo Eloquent al constructor, Laravel serializa solamente el ID. Al ejecutarse el job se recupera el modelo actualizado de la base de datos, con lo que la payload de la cola queda ligera.

Despachar un job

dispatch()

Desde un controlador o servicio, envía el job a la cola con dispatch().

Despacho retrasado

Con delay() retrasas la ejecución.

dispatchAfterResponse()

Ejecuta el job inmediatamente después de devolver la respuesta HTTP al usuario. Funciona incluso con el driver sync, así que es útil para casos ligeros que no necesitan worker.

Despachar a una cola concreta

Queue Routing

Para dirigir por defecto un job a una conexión o cola concreta, usa Queue::route() en el boot() de un service provider. Así centralizas la configuración en vez de repetir onQueue() / onConnection() en cada job.
También puedes usar interfaces, traits o clases padre; se aplica a todos los jobs que las implementen, usen o hereden. Para agrupar varios jobs, pasa un array.
El propio job puede sobreescribir el Queue Routing mediante onQueue() u onConnection().

Ejecución síncrona (para tests y desarrollo)

Con dispatchSync() el job se ejecuta al momento, sin pasar por la cola.

Despacho masivo (bulk)

Cuando necesitas despachar muchos jobs independientes, puedes usar Bus::bulk(). Es ideal si no necesitas seguimiento ni callbacks (como un batch). Bus::bulk() agrupa los jobs por conexión y cola configuradas y los empuja de golpe a la cola, con más eficiencia.
Bus::bulk() envía los jobs agrupados por lotes a la cola. A diferencia del batching (Bus::batch()), no ofrece progreso ni callbacks al terminar. Es la opción sencilla para enviar muchos jobs independientes de una tacada.

Procesar los jobs

Comando queue:work

Arranca un worker para procesar los jobs.
Puedes indicar el driver o la cola concreta.
queue:work se mantiene en ejecución continua. Cuando cambies el código, usa queue:restart para reiniciarlo. En producción se gestiona típicamente con Supervisor u otro process manager.

Opciones para monitorizar el worker

Puedes ajustar el comportamiento del worker con estas opciones.

Configuración de reintentos en la propia clase

En muchos casos es más práctico definir la configuración en el propio job que como opciones de línea de comandos.

Liberar un job (middleware Release)

Si bajo cierta condición quieres devolver el job a la cola sin ejecutarlo, utiliza el middleware Release.
Release::unless() libera cuando la condición es false.
También puedes usar una closure para condiciones más complejas.
Al liberar un job se incrementa igualmente el contador de intentos. Ajusta bien #[Tries] o la propiedad $tries.

Jobs fallidos

Preparar la tabla failed_jobs

Cuando se supera el número de reintentos, los jobs se guardan en failed_jobs. Si no tienes la tabla, créala:

Limpieza al fallar

Definiendo failed() en el job, puedes ejecutar código cuando falle definitivamente.

Detener reintentos por tipo de excepción

Para excepciones que no se resolverán reintentando, indícalas en el withExceptions() de bootstrap/app.php con dontRetry.
Para un control más fino, dontRetryWhen recibe una closure. Si devuelve true, el job se marca como fallido de inmediato.
Con excepciones cuyo resultado no cambia al reintentar (errores de validación, fallos de pago por suscripción caducada…), esta técnica evita reintentos inútiles.

Listar jobs fallidos

Reintentar jobs fallidos

Eliminar jobs fallidos

Drivers de cola habituales

Driver database

Es el más sencillo, se usa sin middleware adicional. Los jobs se guardan en la tabla jobs y el worker hace polling.
  • Ventaja: fácil de configurar, aprovecha la BD existente.
  • Desventaja: carga la base de datos; no es ideal para volúmenes muy altos.

Driver redis

El más habitual en producción por su velocidad. Al trabajar en memoria supera con creces la BD en throughput.
  • Ventajas: rapidez, escalabilidad.
  • Desventaja: requiere un servidor Redis.
En producción con Redis considera adoptar Laravel Horizon. Ofrece un panel bonito y en tiempo real del estado de los jobs.

Operación en producción con Supervisor

En producción es imprescindible reiniciar queue:work automáticamente si cae. En Linux, lo habitual es usar Supervisor.
numprocs=2 arranca 2 workers en paralelo. Recarga Supervisor tras editar la configuración.

Ejemplo práctico: enviar correos desde la cola

1

Crear la clase de job

2

Implementar la lógica

3

Despachar desde el controlador

4

Arrancar el worker

Resumen

  • Envío de correos y SMS.
  • Redimensionado o conversión de imágenes y vídeos.
  • Peticiones a APIs externas.
  • Generación de informes y exportaciones CSV.
  • Envío de webhooks.
Poniendo QUEUE_CONNECTION=sync en .env, los jobs se ejecutan al instante sin cola. Sin necesidad de arrancar un worker, es muy cómodo durante el desarrollo.
Última modificación el 13 de julio de 2026