Skip to main content

Descripción general

La funcionalidad de colas de Laravel ofrece dos tipos de control de ejecución: la deduplicación (Unique) y el debounce (Debounce) de jobs. Ambos mecanismos sirven para «evitar ejecuciones innecesarias cuando el mismo job se despacha varias veces», pero su comportamiento es distinto.
Unique Jobs y Debounced Jobs son excluyentes. No implementes ShouldBeUnique en un job que utilice el atributo DebounceFor.

Unique Jobs — ShouldBeUnique

Mientras el mismo job esté en la cola, se ignoran los despachos adicionales.
Mientras UpdateSearchIndex esté encolado (o en procesamiento), cualquier intento de despachar el mismo job se ignora.

Restringir la unicidad con una clave — UniqueFor + uniqueId()

Si aun tratándose de la misma clase de job quieres tratar «actualizar el producto A» y «actualizar el producto B» como jobs distintos, define la clave con el método uniqueId().
  • El valor devuelto por uniqueId() es la clave del bloqueo en caché.
  • Al indicar #[UniqueFor(segundos)], el bloqueo se libera automáticamente tras esos segundos (medida de seguridad para el caso en que el job no llegue a procesarse).

Especificar el driver de caché — uniqueVia()

Si quieres utilizar un driver de caché distinto al predeterminado, implementa uniqueVia().
Unique Jobs requiere un driver de caché que soporte bloqueos atómicos (redis, database, memcached, dynamodb, file o array).

ShouldBeUnique vs ShouldBeUniqueUntilProcessing

El bloqueo de ShouldBeUnique se mantiene hasta que el job se completa o alcanza el límite de reintentos. Esto puede ser un problema en algunos casos. Ejemplo: hay 1 UpdateSearchIndex(product_id: 42) en la cola y quieres volver a despachar el mismo job justo después de que el worker empiece a procesarlo. Con ShouldBeUnique, el segundo job no se encolará hasta que finalice el procesamiento. En este caso utiliza ShouldBeUniqueUntilProcessing. Como el bloqueo se libera justo antes de comenzar el procesamiento, se puede despachar el siguiente en cuanto el worker toma el job.

Comparativa


Debounced Jobs — #[DebounceFor]

El atributo DebounceFor es una funcionalidad añadida en Laravel 13.
Cuando el mismo job se despacha muchas veces en poco tiempo, se ejecuta solo el último despachado. Es la misma idea que el debounce en un frontend web.
  • El valor devuelto por debounceId() identifica el job (el debounce se aplica de forma independiente por cada ID de producto).
  • Aunque se despache 10 veces con el mismo productId en 30 s, solo se ejecuta el último.

maxWait — límite del tiempo máximo de espera

Con datos que se actualizan con mucha frecuencia, el debounce podría prolongarse indefinidamente y el job podría no ejecutarse nunca. Con maxWait puedes fijar el retraso máximo.
En este ejemplo, el job se ejecuta como muy tarde 120 s después del primer despacho (aunque el debounce de 30 s siga renovándose, se cortará a los 120 s).

Especificar el driver de caché — debounceVia()

Evento JobDebounced

Los jobs que quedan sobrescritos por un despacho posterior emiten el evento Illuminate\Queue\Events\JobDebounced y se eliminan de la cola. Escuchando este evento puedes rastrear y monitorizar los jobs debounced.

Cuál elegir


Implementación interna

Mecanismo de bloqueo de Unique Jobs

Cuando se despacha un job ShouldBeUnique, Laravel obtiene internamente un bloqueo atómico de la caché. La clave del bloqueo tiene el siguiente formato:
Si no se puede obtener el bloqueo (porque otro job ya lo tiene), el job no se añade a la cola.

Implementación de los Debounced Jobs

DebounceFor utiliza internamente una entrada de caché que gestiona una «ventana de debounce». Cada vez que llega un nuevo despacho:
  1. Se elimina el job existente de la cola (emitiendo el evento JobDebounced).
  2. Se añade el nuevo job a la cola (con el retraso indicado por los segundos de debounce).
  3. Se reinicia el temporizador en la caché.
Si maxWait está definido, también se registra la marca de tiempo del primer despacho para evitar que el debounce se prolongue más allá de los segundos de maxWait.

Enlaces de referencia

Última modificación el 2 de agosto de 2026