0Pricing
Apache Kafka & Stream Processing Fundamentals · Lesson

Windowing Operations in Kafka Streams

Learn to define time-based windows for aggregating events in Kafka Streams, including tumbling, hopping, and sliding windows.

Windowing Operations in Kafka Streams is a free Apache Kafka & Stream Processing Fundamentals lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Apache Kafka & Stream Processing Fundamentals learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Intro to Stream Windows

In stream processing, data arrives continuously. To perform calculations like "total sales per hour" or "average temperature every 5 minutes," we need to group these continuous events into finite, manageable segments.

This grouping of events based on time is called windowing. It allows us to apply aggregations and transformations over specific periods.

Why Windowing Matters

Imagine analyzing website clicks. You might want to know:

  • How many clicks happened in the last minute?
  • What's the average user activity over the past 5 minutes, updated every minute?
  • When did a user become inactive?

Windowing provides the framework to answer these questions by defining boundaries around your data streams.

Event Time vs. Processing Time

Kafka Streams primarily uses event time. This is the timestamp embedded in the event itself, indicating when the event actually happened at the source.

  • Event Time: When the event occurred (preferred).
  • Processing Time: When the event is processed by the stream application (less reliable for ordering).

Using event time ensures that results are consistent, even if events arrive out of order or with delays.

Tumbling Windows: Fixed & Non-Overlapping

Tumbling windows are like non-overlapping, fixed-size buckets of time. Each event belongs to exactly one window.

  • They are fixed in duration (e.g., 5 minutes).
  • They do not overlap.
  • They are contiguous, covering all time.

Think of them as a series of distinct time slots, where each event falls into one specific slot.

Tumbling Window Code

Here's how to define a 5-second tumbling window in Kafka Streams to count messages. We use TimeWindows.of() and count().

import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.Consumed;
import org.apache.kafka.streams.kstream.Materialized;
import org.apache.kafka.streams.kstream.TimeWindows;
import java.time.Duration;
import java.util.Properties;

public class TumblingWindowApp {

  public static void main(String[] args) {
    Properties props = new Properties();
    props.put(StreamsConfig.APPLICATION_ID_CONFIG, "tumbling-window-app");
    props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
    props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());

    StreamsBuilder builder = new StreamsBuilder();
    builder.stream("input-topic", Consumed.with(Serdes.String(), Serdes.String()))
           .groupByKey()
           .windowedBy(TimeWindows.of(Duration.ofSeconds(5))) // 5-second tumbling window
           .count(Materialized.as("tumble-counts"))
           .toStream()
           .print(org.apache.kafka.streams.kstream.Printed.toSysOut());

    KafkaStreams streams = new KafkaStreams(builder.build(), props);
    streams.start();
    Runtime.getRuntime().addShutdownHook(new Thread(streams::close));
  }
}

Hopping Windows: Overlapping & Moving

Hopping windows are also fixed-size, but they can overlap. They "hop" forward by a specified interval, which is typically smaller than the window size.

  • Fixed size (e.g., 10 minutes).
  • Overlap with previous/next windows.
  • Hop interval (e.g., moves every 5 minutes).

This allows for smoother, more frequently updated aggregations, as a new window result is emitted more often.

Hopping Window Code

Here's how to create a 10-second hopping window that advances every 5 seconds. Events will be counted in multiple overlapping windows.

import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.Consumed;
import org.apache.kafka.streams.kstream.Materialized;
import org.apache.kafka.streams.kstream.TimeWindows;
import java.time.Duration;
import java.util.Properties;

public class HoppingWindowApp {

  public static void main(String[] args) {
    Properties props = new Properties();
    props.put(StreamsConfig.APPLICATION_ID_CONFIG, "hopping-window-app");
    props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
    props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());

    StreamsBuilder builder = new StreamsBuilder();
    builder.stream("input-topic", Consumed.with(Serdes.String(), Serdes.String()))
           .groupByKey()
           .windowedBy(TimeWindows.of(Duration.ofSeconds(10)) // 10-second window
                                  .advanceBy(Duration.ofSeconds(5))) // hops every 5 seconds
           .count(Materialized.as("hop-counts"))
           .toStream()
           .print(org.apache.kafka.streams.kstream.Printed.toSysOut());

    KafkaStreams streams = new KafkaStreams(builder.build(), props);
    streams.start();
    Runtime.getRuntime().addShutdownHook(new Thread(streams::close));
  }
}

Session Windows: Data-Driven Activity

Session windows are different. They are data-driven, not fixed-time. They group events that occur within a specified "inactivity gap."

  • Window closes if no new event for a key arrives within the gap duration.
  • Variable size, non-overlapping for a given key.
  • Useful for user activity tracking or network sessions.

If a new event arrives for the same key after the inactivity gap, a new session window starts.

Session Window Code

This example shows how to define a session window with a 5-second inactivity gap. If a key doesn't receive an event for 5 seconds, its current session window closes.

import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.kstream.Consumed;
import org.apache.kafka.streams.kstream.Materialized;
import org.apache.kafka.streams.kstream.SessionWindows;
import java.time.Duration;
import java.util.Properties;

public class SessionWindowApp {

  public static void main(String[] args) {
    Properties props = new Properties();
    props.put(StreamsConfig.APPLICATION_ID_CONFIG, "session-window-app");
    props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
    props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());

    StreamsBuilder builder = new StreamsBuilder();
    builder.stream("input-topic", Consumed.with(Serdes.String(), Serdes.String()))
           .groupByKey()
           .windowedBy(SessionWindows.with(Duration.ofSeconds(5))) // 5-second inactivity gap
           .count(Materialized.as("session-counts"))
           .toStream()
           .print(org.apache.kafka.streams.kstream.Printed.toSysOut());

    KafkaStreams streams = new KafkaStreams(builder.build(), props);
    streams.start();
    Runtime.getRuntime().addShutdownHook(new Thread(streams::close));
  }
}

Grace Period for Late Events

Events don't always arrive in order or on time. Kafka Streams handles this with a grace period.

  • It's extra time a window stays open to accept late-arriving records.
  • Defined as part of the window definition (e.g., .grace(Duration.ofSeconds(10))).
  • Events arriving after the grace period are typically dropped or forwarded to a late record topic.

This helps ensure accuracy for aggregations over event time.

Check Your Understanding

Which of the following statements about Kafka Streams windowing are TRUE?

Recap: Windowing in Kafka Streams

We've explored how windowing allows us to perform time-based aggregations on continuous data streams in Kafka Streams.

  • Tumbling windows: Fixed, non-overlapping.
  • Hopping windows: Fixed, overlapping, advance by an interval.
  • Session windows: Data-driven, based on an inactivity gap.
  • Grace period: Important for handling late-arriving events.

Mastering these window types is crucial for building robust real-time analytics and stream processing applications.

Frequently asked questions

Is the “Windowing Operations in Kafka Streams” lesson free?

Yes — the full text of “Windowing Operations in Kafka Streams” is free to read here on the web, and the Apache Kafka & Stream Processing Fundamentals course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Apache Kafka & Stream Processing Fundamentals course, upgrade to CoddyKit PRO.

What will I learn in “Windowing Operations in Kafka Streams”?

Learn to define time-based windows for aggregating events in Kafka Streams, including tumbling, hopping, and sliding windows. You practise Apache Kafka & Stream Processing Fundamentals with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Apache Kafka & Stream Processing Fundamentals?

No prior experience is required. Apache Kafka & Stream Processing Fundamentals on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Windowing Operations in Kafka Streams” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Apache Kafka & Stream Processing Fundamentals lesson?

Yes. Every Apache Kafka & Stream Processing Fundamentals lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Windowing Operations in Kafka Streams
  2. Joins & Aggregations in Streams
  3. Introduction to KSQL for Stream Analytics
  4. Interactive Queries & State Stores
← Back to Apache Kafka & Stream Processing Fundamentals