Confluent publica una referencia exhaustiva sobre watermarks en Apache Flink
El primer artículo de una serie de dos partes repasa generación, propagación, alineación y eventos tardíos en Flink SQL y Table API, con las trampas al operar.

Confluent ha publicado la primera entrega de una guía sobre watermarks en Apache Flink, el mecanismo que determina cuándo un operador basado en tiempo puede dar por cerrada una ventana. No es una introducción al event-time ni al processing-time: da por hechas esas bases y entra directo en cómo se generan, cómo se propagan y cómo los consumen los operadores. El autor trabaja en Confluent y el texto nace de una molestia concreta: hay buenas introducciones al concepto, pero no una referencia exhaustiva a la que ir a consultar un detalle suelto.
El mecanismo
Un watermark es una señal que Flink inyecta periódicamente en el flujo de registros, con una marca de tiempo expresada en milisegundos desde la epoch. El término es ambiguo incluso dentro del proyecto: designa tanto ese timestamp que usa un operador para su lógica temporal como la señal que viaja por el dataflow para propagarlo.
Cada subtask mantiene su propia marca de tiempo de forma independiente y la emite hacia abajo por sus channels, hasta que el valor alcanza los sinks. La marca de un subtask sale del mínimo, el más antiguo, entre sus entradas activas, es decir, las que no están idle. En un subtask de origen ese valor es el máximo event-time observado en cada partición de Kafka.
Para qué sirve y para qué no
Los operadores temporales son los que tiran de watermarks: ventanas de tiempo y joins temporales, por ejemplo. Una ventana que termina en T se cierra cuando el operador ve un watermark con tiempo mayor o igual a T: en ese momento dispara el cálculo, emite el resultado y libera el estado.
Todo lo que no dependa del tiempo pasa de ellos. Un JOIN normal, un UNION ALL o un filtro por WHERE no los usan. Tampoco el TTL del estado, que se rige por el reloj de sistema, ni el modo batch ni las consultas sobre snapshots. Y hay un detalle que se escapa a menudo: aunque ninguna operación sea temporal, si los watermarks están definidos siguen fluyendo, y la alineación entre ellos puede cambiar a qué velocidad se consumen unas particiones y otras.
Los eventos tardíos merecen párrafo aparte. Cualquier evento cuyo event-time sea igual o anterior al watermark del operador se considera tardío, y la mayoría de los operadores temporales lo descarta sin avisar. Los interval joins lo tratan de otra forma, y el artículo enlaza el código de RowTimeIntervalJoin donde se ve ese comportamiento.
El texto se limita a Flink SQL y Table API y a fuentes que leen de Kafka, aunque las tripas de los watermarks valgan para cualquier API. Queda anunciada una segunda parte centrada en Confluent Cloud for Apache Flink y en las extensiones que añade, como la detección progresiva de particiones idle.
Para quien opera jobs con ventanas o joins temporales, lo aprovechable está en los casos límite: particiones idle que bloquean el avance del watermark, la alineación entre fuentes y el hecho de que el retraso no sea determinista. Son justo los puntos donde un pipeline se atasca sin devolver un error claro.

