Learn Labs
4. Kafka Consumers: Reading Data from Kafka

4.12 Standalone consumer — `assign()` instead of `subscribe()`

When: "Sometimes you know you have a single consumer that always needs to read data from all the partitions in a topic, or from a specific partition in a topic. In this case, there is no reason for groups or rebalances — just assign the consumer-specific topic and/or partitions, consume messages, and commit offsets on occasion."

⚠️ "although you still need to configure group.id to commit offsets — without calling subscribe, the consumer won't join any group."

A consumer can EITHER subscribe() to topics (and be part of a consumer group) OR assign() itself partitions — BUT NOT BOTH at the same time.

Duration timeout = Duration.ofMillis(100);
List<PartitionInfo> partitionInfos = null;
partitionInfos = consumer.partitionsFor("topic");        // ① ask the cluster

if (partitionInfos != null) {
    for (PartitionInfo partition : partitionInfos)
        partitions.add(new TopicPartition(partition.topic(),
            partition.partition()));
    consumer.assign(partitions);                        // ② assign, don't subscribe

    while (true) {
        ConsumerRecords<String, String> records = consumer.poll(timeout);
        for (ConsumerRecord<String, String> record: records) {
            /* process */
        }
        consumer.commitSync();
    }
}

⚠️ "Keep in mind that if someone adds new partitions to the topic, the consumer will NOT be notified. You will need to handle this by checking consumer.partitionsFor() periodically, or simply by bouncing the application whenever partitions are added."*

Trade-off summary:

subscribe() + groupassign() standalone
✓ automatic rebalancing✓ NO rebalances ever (deterministic)
✓ automatic failover✓ full control over which partitions
✓ horizontal scaling✗ NO failover — if it dies, nothing reads
✗ rebalance pauses✗ NO notification of new partitions
✗ assignment not in your control✗ you scale it yourself