Mario Ruiz Díaz
← Todos los casos

Caso de estudio · Sistemas distribuidos

Frequency capping para los anuncios de Pluto TV: reglas, cuotas y 24 horas de impresiones

Un sistema basado en reglas, en producción, que evita que los espectadores vean el mismo anuncio una y otra vez entre cortes, construido sobre Kafka para unos 6k eventos de impresión por segundo con 10x de margen.

Visitar pluto.tv
Producto
pluto.tv ↗
Cliente
Pluto TV
Industria
Streaming gratuito con publicidad (FAST)
Rol
Tech Lead · Diseñador de la solución
Período
2021 – 2024
Live
en producción en Pluto TV
24 h
de impresiones por dispositivo
~6k/s
eventos de impresión
10x
margen sobre el peor caso
Frequency capping para los anuncios de Pluto TV: reglas, cuotas y 24 horas de impresionesAPPS DE LOS ESPECTADORESLECTURAALMACENAMIENTOESCRITURAAppsmobile · web · TVStitcherstreams VOD · linealServicio adPodpods de FreeWheel · deduplicar · filtraradSelectioncuotas restantes al corteReglasgenéricas · específicas · prevalenciaContadores de cuotaventana deslizante por reglaHistorial de impresionesRedis · 24 h · ~120 GBAPI ad-beaconeventos de anuncios · ~6k/sKafkaNEW_IMPRESSION · ~12k/sEscritor de historialinserción por dispositivoGestor de cuotasactualiza contadores por reglaJobs de limpiezavencen ventanas viejasstreamanuncio vistofiltrar por cuotaentrada insertada

Deslizá hacia el costado para ver el diagrama completo →

Frequency capping de Pluto TV. Las apps reportan los anuncios vistos por un camino de escritura sobre Kafka que mantiene el historial de impresiones y los contadores de cuota; el camino de entrega le pide a adSelection las cuotas restantes en el momento del corte.Descargar diagrama (PNG) ↓

Contexto

Ver el mismo anuncio una y otra vez en el mismo corte o en la misma hora es una mala experiencia: la gente se desconecta cuando siente que le martillan el mismo mensaje. Pluto TV ya detectaba duplicados dentro de un mismo corte, pero no entre cortes.

El desafío

Extender la deduplicación entre cortes con un frequency cap propio (el mismo anuncio como máximo X veces cada Y minutos por espectador), configurable con reglas de negocio, decidido en el momento del corte sobre el camino de entrega y alimentado por los eventos de impresión de todos los dispositivos a escala de producción.

La solución

Dos caminos desacoplados alrededor de un almacenamiento compartido. El camino de escritura ingiere los eventos de anuncios vistos por Kafka, guarda 24 horas de impresiones por dispositivo y actualiza los contadores de cuota por regla. El camino de lectura, donde el servicio de ad pods llena los cortes desde FreeWheel, le pide a un servicio adSelection las cuotas restantes de cada dispositivo, y las calcula a partir de las reglas en el momento si todavía no hay contadores.

  • Reglas con prevalencia

    Reglas genéricas (repetición por creatividad, marca e industria) y específicas por marca o creatividad, incluido OFF. Las específicas le ganan a las genéricas, y la creatividad le gana a la marca, que le gana a la industria.

  • Historial de impresiones de 24 horas

    Una entrada por anuncio visto y por dispositivo, con fingerprint, marca e industria, guardada en Redis durante 24 horas.

  • Contadores de cuota con ventana deslizante

    Cada impresión abre una ventana por regla y dimensión aplicable; solo cuentan contra el límite las impresiones cuya ventana sigue abierta.

  • Servicio adSelection

    Encapsula la decisión: devuelve las cuotas restantes de un dispositivo en el momento absoluto del corte, para que el servicio de ad pods pueda filtrar las creatividades.

  • Camino de escritura por eventos

    Una API ad-beacon publica eventos NEW_IMPRESSION en Kafka; consumers independientes insertan el historial, actualizan cuotas y limpian ventanas vencidas.

Decisiones clave

  1. 01

    Decidir en el momento absoluto del corte

    Si un anuncio está permitido depende de qué impresiones siguen dentro de su ventana cuando se reproduce el corte, no cuando se pidió. El mismo historial puede permitir un anuncio a las 9:00 y bloquearlo a las 8:30.

  2. 02

    Reglas como datos, con prevalencia explícita

    Operaciones de ads necesitaba ajustar la repetición sin deploys. Modelar las reglas por tipo (genéricas, específicas) y dimensión (creatividad, marca, industria) con un orden de prevalencia claro mantuvo el comportamiento predecible.

    Alternativas evaluadas Límites fijos en código por campaña.

  3. 03

    Precalcular cuotas, con fallback a reglas

    El camino de entrega lee contadores precalculados para ser rápido; cuando un dispositivo todavía no tiene contadores, adSelection evalúa las reglas en el momento en lugar de bloquear el corte.

  4. 04

    Desacoplado mediante Kafka

    Los servicios solo conocen el stream de eventos, no se conocen entre sí. Ingesta, historial, cuotas y limpieza escalan y fallan de forma independiente, y el diseño sigue siendo agnóstico de la nube.

  5. 05

    Dimensionado para 10x

    La capacidad se planificó con seis meses de métricas de producción en el peor caso: unos 6k requests de impresión por segundo en el beacon, 12k mensajes por segundo en Kafka y unos 120 GB de historial de impresiones, con la exigencia de que la implementación soportara diez veces esos valores.

Qué hice

  • Diseñé la solución: modelo de reglas, prevalencia, cuotas con ventana deslizante y la decisión en el momento del corte.
  • Diseñé la arquitectura: caminos de lectura y escritura desacoplados, almacenamiento y eventos en Kafka.
  • Dimensioné el sistema a partir de métricas de producción, con margen de 10x.
  • Lideré la implementación como Tech Lead, del design review a producción.

Resultados

  • En producción: frequency caps aplicados en todos los cortes que ve un espectador.
  • Deduplicación extendida de un solo corte a 24 horas de impresiones por dispositivo.
  • Un camino de escritura construido para unos 6k requests de impresión y 12k mensajes de Kafka por segundo.
  • Capacidad planificada para diez veces la carga de producción en el peor caso.
  • Repetición controlada por reglas de negocio que operaciones de ads puede cambiar sin deploys.

Fuentes y prensa

Contacto

Traeme un problema real.

Un problema de escalado, una migración riesgosa, un workflow de IA que tiene que volverse confiable o un equipo que necesita una dirección técnica más clara.

Conversación de nivel founder · Feedback práctico · NDA disponible a pedido