Stream topology in Kafka - Time & Space Complexity
When working with Kafka stream topology, it's important to understand how the processing time grows as the data flows through the stream steps.
We want to know how the number of operations changes as the input data size increases in the stream.
Analyze the time complexity of the following Kafka Streams topology setup.
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> source = builder.stream("input-topic");
KStream<String, String> filtered = source.filter((key, value) -> value.contains("important"));
KStream<String, String> mapped = filtered.mapValues(value -> value.toUpperCase());
mapped.to("output-topic");
KafkaStreams streams = new KafkaStreams(builder.build(), props);
streams.start();
This code creates a stream that reads messages, filters them by a condition, transforms the values, and writes to an output topic.
Look at the operations that happen repeatedly for each message in the stream.
- Primary operation: Processing each message through filter and map steps.
- How many times: Once per message arriving in the input topic.
Each message is processed one by one through the steps, so the total work grows as more messages arrive.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 filter and map operations |
| 100 | About 100 filter and map operations |
| 1000 | About 1000 filter and map operations |
Pattern observation: The work grows linearly with the number of messages.
Time Complexity: O(n)
This means the processing time increases directly in proportion to the number of messages.
[X] Wrong: "The filter and map steps run only once regardless of input size."
[OK] Correct: Each message is processed individually, so these steps happen for every message, making the total work grow with input size.
Understanding how stream processing scales with data size helps you explain system behavior clearly and shows you grasp real-world data flow challenges.
"What if we added a nested loop inside the mapValues step that processes each message multiple times? How would the time complexity change?"
Practice
Solution
Step 1: Understand the role of topology in Kafka Streams
A topology defines how data flows and is processed in a Kafka Streams app.Step 2: Differentiate topology from other Kafka concepts
It is not about broker configs, topic lists, or message schemas, but about processing steps.Final Answer:
The flow and processing steps of data in a Kafka Streams application -> Option BQuick Check:
Topology = Data flow and processing [OK]
- Confusing topology with Kafka broker settings
- Thinking topology lists topics
- Assuming topology defines message schema
Solution
Step 1: Recall the correct method to build topology
The method to finalize and get the topology isbuild().Step 2: Check each option's method
Only StreamsBuilder builder = new StreamsBuilder(); builder.build(); usesbuild(), others use invalid methods.Final Answer:
StreamsBuilder builder = new StreamsBuilder(); builder.build(); -> Option DQuick Check:
Use build() to create topology [OK]
- Using start(), create(), or run() instead of build()
- Confusing topology building with starting the stream
StreamsBuilder builder = new StreamsBuilder();
builder.stream("input-topic").mapValues(value -> value.toUpperCase()).to("output-topic");
Topology topology = builder.build();
System.out.println(topology.describe());What will the printed topology description include?
Solution
Step 1: Analyze the stream processing steps
The code reads from 'input-topic', applies mapValues to uppercase, then writes to 'output-topic'.Step 2: Understand topology description output
The description shows source nodes (input), processor nodes (mapValues), and sink nodes (output).Final Answer:
A source node for 'input-topic', a processor node for mapValues, and a sink node for 'output-topic' -> Option CQuick Check:
Topology describe shows source, processor, sink [OK]
- Thinking mapValues is not part of topology
- Confusing source and sink nodes
- Expecting no processor nodes in description
StreamsBuilder builder = new StreamsBuilder();
builder.stream("input-topic").filter(value -> value.length() > 5);
Topology topology = builder.build();
System.out.println(topology.describe());Solution
Step 1: Check the stream processing chain
The code filters the stream but does not write the result to any output topic.Step 2: Understand topology implications
Without a sink node, the topology has no output, which is usually an error or incomplete.Final Answer:
The filtered stream is not sent to any sink topic, so no output node is created -> Option AQuick Check:
Missing sink node causes incomplete topology [OK]
- Assuming filter causes syntax error
- Thinking build() requires no streams
- Ignoring missing sink topic after processing
Solution
Step 1: Understand the requirement
Read from two topics, merge streams, filter messages with 'error', write to output.Step 2: Evaluate each option
StreamsBuilder builder = new StreamsBuilder(); KStream stream1 = builder.stream("topic1"); KStream stream2 = builder.stream("topic2"); KStream merged = stream1.merge(stream2); merged.filter((k, v) -> v.contains("error")).to("output-topic"); Topology topology = builder.build(); merges streams correctly, filters, then writes once. StreamsBuilder builder = new StreamsBuilder(); KStream stream = builder.stream("topic1", "topic2"); stream.filter(v -> v.contains("error")).to("output-topic"); Topology topology = builder.build(); incorrectly tries to stream two topics in one call. StreamsBuilder builder = new StreamsBuilder(); KStream stream1 = builder.stream("topic1"); KStream stream2 = builder.stream("topic2"); KStream merged = stream1.join(stream2, (v1, v2) -> v1 + v2); merged.filter((k, v) -> v.contains("error")).to("output-topic"); Topology topology = builder.build(); joins streams (not merge). StreamsBuilder builder = new StreamsBuilder(); builder.stream("topic1").filter(v -> v.contains("error")).to("output-topic"); builder.stream("topic2").filter(v -> v.contains("error")).to("output-topic"); Topology topology = builder.build(); filters separately and writes twice, not merging.Final Answer:
Option A correctly merges, filters, and writes to output topic -> Option AQuick Check:
Merge streams, filter, then write [OK]
- Using join instead of merge for combining streams
- Trying to stream multiple topics in one call incorrectly
- Writing filtered streams separately without merging
Ready to prove it?
Pass the test and this pattern moves unknown
