Skip to main content

Qué es la clase Lottery

Illuminate\Support\Lottery es una utilidad que expresa operaciones basadas en probabilidad con una API fluida. Permite describir de forma sencilla patrones como «ejecuta este proceso solo 1 vez cada 100 peticiones» o «registra logs detallados solo en una fracción de las peticiones».
La implementación está en src/Illuminate/Support/Lottery.php. Laravel también la utiliza internamente, por ejemplo en el GC de sesiones o para podar locks de caché.

Uso básico

Indicar la probabilidad mediante enteros

Con Lottery::odds($chances, $outOf) indicas la probabilidad «gana $chances de cada $outOf intentos».

Indicar la probabilidad con un decimal

Si omites $outOf y pasas un decimal entre 0.0 y 1.0, se usa directamente como probabilidad.
Con la especificación decimal, si el valor supera 1.0 se lanza RuntimeException.

Devolver un booleano sin callbacks

Si no configuras winner ni loser, choose() devuelve true si gana y false si pierde.

Ejecutar varias veces

Pasando el número de veces a choose($times), se devuelve un array con los resultados.

Pasarlo como callable

Como la instancia de Lottery implementa __invoke, la puedes pasar directamente a APIs que reciban un callable.

Casos de uso prácticos

1. Poda de caché (una vez cada 100)

Ideal para tareas de mantenimiento como el borrado de registros expirados, que no hace falta ejecutar en cada petición.

2. Sampling de telemetría (log detallado solo en algunas peticiones)

Cuando registrar el log de todas las peticiones es caro, resulta útil para muestreo.

3. Comportamiento estilo A/B testing

Reparte a los usuarios entre dos caminos de código de forma probabilística.

4. Ejecución aleatoria de tareas periódicas junto al scheduler

Cuando quieres ejecutar una tarea de vez en cuando evitando duplicados entre varios servidores.

Patrones probabilísticos dentro del framework Laravel

Laravel utiliza ampliamente el patrón probabilístico para tareas de mantenimiento internas. Parte de esas implementaciones se escribieron antes de que existiera la clase Lottery, así que usan random_int() directamente, pero comparten la misma idea.
1

Session: garbage collection

Illuminate\Session\Middleware\StartSession::configHitsLottery() utiliza el ajuste lottery de config/session.php y decide con random_int si ejecutar el GC.
2

DatabaseLock: poda de locks caducados

Illuminate\Cache\DatabaseLock::acquire() aplica el mismo patrón para eliminar locks expirados en cada adquisición.
3

DB::whenQueryingForLongerThan — ejemplo pasando una Lottery

Como una instancia de Lottery es un callable, se puede pasar directamente como callback de detección de consultas lentas.
Frente a Session y DatabaseLock, que usan random_int() directamente, la clase Lottery te permite controlar el resultado durante los tests con alwaysWin() / alwaysLose() / fix(). En el desarrollo de paquetes, optar por Lottery mejora la testabilidad.

Uso en pruebas

Para testear código con aleatoriedad, usa las APIs de test que ofrece Lottery.

Lottery::alwaysWin() — gana siempre

Lottery::alwaysLose() — pierde siempre

Lottery::fix() — fija los resultados con una secuencia

Puedes controlar el resultado de varias llamadas con un array de true/false.
alwaysWin() / alwaysLose() / fix() alteran una propiedad estática global. Llama siempre a Lottery::determineResultNormally() en el tearDown() de tu test.

Lottery::setResultFactory() — inyectar una factory personalizada

Si necesitas un control más fino, usa una factory personalizada.

Uso en el desarrollo de paquetes

Registro en el service provider

Si integras una tarea de mantenimiento en el service provider de un paquete, distribuye la carga con Lottery.

Leer las odds desde configuración

Facilita al usuario ajustar la probabilidad exponiéndola en el archivo de configuración.

Sampling en un middleware

Referencia de la API

Páginas relacionadas

Trait Macroable

Aprende el patrón de extensión para añadir métodos nuevos a clases existentes.

Trait Conditionable

Aprende cómo diseñar cadenas con bifurcaciones condicionales usando when() / unless().
Última modificación el 13 de julio de 2026