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 enconfig/queue.php.
La variable QUEUE_CONNECTION selecciona el driver.
Configuración en .env
Preparar el driver de base de datos
Si usasdatabase, 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 enconfig/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_processingelimina el payload al finalizar con éxito (por defectotrue).flush_on_clear: truevacía el store de overflow al ejecutarqueue: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.
app/Jobs/SendWelcomeEmail.php.
Estructura de la clase
ShouldQueue, indicamos a Laravel que este job debe procesarse en cola.
El trait Queueable aporta los métodos necesarios para operar sobre la cola.
Despachar un job
dispatch()
Desde un controlador o servicio, envía el job a la cola con dispatch().
Despacho retrasado
Condelay() 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, usaQueue::route() en el boot() de un service provider. Así centralizas la configuración en vez de repetir onQueue() / onConnection() en cada job.
El propio job puede sobreescribir el Queue Routing mediante
onQueue() u onConnection().Reenvío de colas (Queue::forward())
Con Queue::forward() puedes reenviar los jobs de una cola a otra cola o conexión. Resulta útil cuando quieres cambiar la infraestructura de colas sin modificar cada job ni el código que los despacha.
Si el job especifica explícitamente una conexión, esa indicación tiene prioridad sobre la configuración de reenvío.
Ejecución síncrona (para tests y desarrollo)
CondispatchSync() el job se ejecuta al momento, sin pasar por la cola.
Despacho masivo (bulk)
Cuando necesitas despachar muchos jobs independientes, puedes usarBus::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.Encadenar jobs (chains)
Encadenar jobs permite ejecutar varios jobs en orden secuencial. Si un job de la cadena falla, los jobs posteriores no se ejecutan.Batches de jobs
Los batches permiten despachar varios jobs a la vez y hacer seguimiento del progreso del conjunto. Primero, crea la migración para la tablajob_batches.
Batchable en la clase del job.
Bus::batch() y registra callbacks para la finalización, el fallo y el término de la ejecución.
Procesar los jobs
Comando queue:work
Arranca un worker para procesar los jobs.
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.Contar los fallos del proceso como excepciones
Por defecto, los intentos que terminan porque el proceso del worker falla o se cierra a la fuerza, por ejemplo por falta de memoria, no cuentan para el número máximo de excepciones del job (MaxExceptions). Si quieres que estos intentos también cuenten como excepciones, añade el atributo CountCrashesAsExceptions a la clase del job.
Controlar la ejecución con middleware de jobs
Con los middleware de jobs puedes separar del métodohandle() lógica transversal como el rate limiting o la prevención de ejecuciones simultáneas, y declararla en el método middleware(). Al no escribir esa lógica en el propio job, es más fácil reutilizar el mismo control en varios jobs.
Limitación de tasa (RateLimited)
Define un limitador con el métodofor de la facade RateLimiter y aplica el middleware Illuminate\Queue\Middleware\RateLimited al job.
releaseAfter(), o terminar el job sin reintentarlo con dontRelease().
Illuminate\Queue\Middleware\RateLimitedWithRedis.
Prevención de ejecuciones simultáneas (WithoutOverlapping)
Illuminate\Queue\Middleware\WithoutOverlapping evita que el mismo job se ejecute varias veces en paralelo tomando como referencia una clave arbitraria. Es útil cuando quieres actualizar un recurso concreto de uno en uno.
releaseAfter() o eliminarlos de inmediato con dontRelease(). Como el lock se apoya en la funcionalidad de locks atómicos, es recomendable definir su caducidad con expireAfter() para que el lock no quede colgado si el job falla o expira de forma inesperada.
Por defecto los solapamientos se detectan solo dentro de la misma clase de job. Si quieres compartir la clave del lock entre distintas clases de jobs, utiliza el método
shared().Contención de excepciones consecutivas (ThrottlesExceptions)
Illuminate\Queue\Middleware\ThrottlesExceptions es un mecanismo pensado para jobs que se comunican con servicios inestables (APIs externas, por ejemplo): cuando se produce un número determinado de excepciones seguidas, pausa temporalmente las ejecuciones posteriores. Habitualmente se combina con el límite de reintentos basado en tiempo (retryUntil()).
when() puedes limitar la contención a determinadas excepciones y con deleteWhen() eliminar el job si se produce una excepción concreta, lo que permite un control muy fino.
Illuminate\Queue\Middleware\ThrottlesExceptionsWithRedis permite aplicar la contención de forma más eficiente.
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.
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
Definiendofailed() 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 elwithExceptions() de bootstrap/app.php con dontRetry.
dontRetryWhen recibe una closure. Si devuelve true, el job se marca como fallido de inmediato.
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.
Operación en producción con Supervisor
En producción es imprescindible reiniciarqueue: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
Cuándo usar colas
Cuándo usar colas
- 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.
Consejos para desarrollo
Consejos para desarrollo
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.Comandos habituales
Comandos habituales