Window functions

Updated at:
Copy as MD

Flink SQL supports TUMBLE, HOP, and SESSION window functions based on event time or processing time.

Window functions

Flink SQL supports aggregation over infinite windows without explicitly defining windows in SQL statements. It also supports aggregation over a specific window. For example, to count users who clicked a URL in the previous minute, define a window that collects the last minute of click data and computes the result.

Flink SQL supports window aggregates and over aggregates. This topic covers window aggregates. Window aggregates use two time attributes — event time and processing time — and support the TUMBLE, HOP, and SESSION window functions.

Warning

Window aggregations (TUMBLE, HOP, and SESSION) combined with LAST_VALUE, FIRST_VALUE, or TopN functions may yield inaccurate results due to window triggering mechanisms or latencies.

Time attributes

Flink SQL supports two time attributes: event time and processing time. The windowing behavior differs based on which attribute you use.

  • Event time: typically the timestamp embedded in a record.

    A window closes when the watermark exceeds the window end time. Output is generated only when closing data arrives. For a single subtask, the watermark increments monotonically. With multiple subtasks or source tables, Flink uses the minimum watermark value.

    Important
    • If out-of-order records exist or a subtask or partition has no data, the watermark cannot advance and the window may not close. To resolve this, specify a watermark offset for out-of-order data, and ensure all subtasks and partitions have data flowing in. If a partition is idle, add table.exec.source.idle-timeout: 10s to the Other Configuration field in Parameters on the Configuration tab of the Deployments page. See Configuration for parameter details.

    • After data is processed by using GROUP BY, JOIN operations on two data streams, or OVER window nodes, the watermark property is lost and the event time can no longer be used for windowing.

  • Processing time: the system clock time when Flink processes an event.

    Processing time is generated by Flink and does not exist in your raw data, so you must explicitly define a processing time column.

    Note

    Because processing time depends on event arrival speed and processing order, backtrack results may differ between runs.

Cascading window aggregations

After a window aggregation completes, the rowtime column loses its event time attribute. Use helper functions such as TUMBLE_ROWTIME, HOP_ROWTIME, or SESSION_ROWTIME to retrieve max(rowtime) of the window and use it as the new rowtime. The returned value equals window_end - 1, is of the TIMESTAMP type, and retains the rowtime attribute. For example, for window [00:00, 00:15), the value 00:14:59.999 is returned.

The following example cascades a 1-hour tumbling window on top of a 1-minute tumbling window:

CREATE TEMPORARY TABLE user_clicks(
  username varchar,
  click_url varchar,
  eventtime varchar,                                                        
  ts AS TO_TIMESTAMP(eventtime),
  WATERMARK FOR ts AS ts - INTERVAL '2' SECOND   -- Define a watermark for rowtime. 
) with (
  'connector'='sls',
  ...
);

CREATE TEMPORARY TABLE tumble_output(
  window_start TIMESTAMP,
  window_end TIMESTAMP,
  username VARCHAR,
  clicks BIGINT
) with (
  'connector'='datahub'        -- Simple Log Service allows you to export only VARCHAR-type DDL statements. Therefore, DataHub is used to store data. 
  ...
);

CREATE TEMPORARY VIEW one_minute_window_output AS 
SELECT 
  TUMBLE_ROWTIME(ts, INTERVAL '1' MINUTE) as rowtime,  -- Use TUMBLE_ROWTIME as the aggregation time of the level-two window. 
  username, 
  COUNT(click_url) as cnt
FROM user_clicks
GROUP BY TUMBLE(ts, INTERVAL '1' MINUTE),username;

BEGIN statement set;
INSERT INTO tumble_output
SELECT
  TUMBLE_START(rowtime, INTERVAL '1' HOUR),
  TUMBLE_END(rowtime, INTERVAL '1' HOUR),
  username,
  SUM(cnt)
FROM one_minute_window_output
GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), username;
END;

Intermediate results

Window intermediate data consists of keyed state and timer data, each stored in different backends. Choose a combination based on your job characteristics:

Storage for keyed state

Storage for timers

GeminiStateBackend

Memory

HashMapStateBackend

Memory

RocksDBStateBackend

Memory

RocksDBStateBackend

File

Timers are mainly used to trigger expired windows. Store timers in memory for best performance. If timers are numerous or memory is limited, use RocksDBStateBackend to store them in a RocksDB file.