Apache Kafka Topic
In Apache Kafka, a topic is a named category or channel where related messages are stored and organized. Producers write messages to topics, and consumers read from them.
This guide explains how topics work, how they relate to partitions, offsets and replication, and how to create, configure, change and delete them with the command line, Java and Spring Boot, plus best practices for naming, retention and partition counts.
1. What Is a Kafka Topic?
Think of a Kafka topic like a TV channel. Each channel focuses on one kind of content, and viewers choose which channels to watch. In the same way, each topic holds one kind of data, such as orders or page views, and applications choose which topics to read.
Kafka does not change the data in a topic. It only stores and delivers it efficiently, in order, to everyone who reads the topic.
2. Key Features of a Kafka Topic
| Feature | What it means |
|---|---|
| Named stream of data | Each topic has a unique name describing its data, such as order-events or user-logs |
| Append-only | New messages are always added at the end; producers never modify existing messages |
| Partitioned | A topic is split into partitions, so it can handle large volumes and parallel processing |
| Ordered within a partition | Messages in one partition keep the order in which they arrived |
| Durable | Messages are stored on disk and remain available after restarts |
| Multiple consumers | Many consumer groups can read the same topic independently |
| Configurable retention | Data is kept for a set time, such as 7 days, or until a size limit is reached |
3. Topics, Partitions and Offsets
A topic is a logical name. Physically, it is made of one or more partitions, and each partition is an ordered log of messages. Each message in a partition has a position number called its offset.
orders-0: [0] [1] [2] [3] [4]
orders-1: [0] [1] [2]
orders-2: [0] [1] [2] [3]
Each partition has its own offsets, starting at 0.
Messages with the same key always go to the same partition.
- Partitions let a topic be spread across several brokers and read by several consumers in parallel.
- Order is guaranteed within a partition, not across the whole topic.
- Consumers remember their progress as offsets, so they can continue after a restart or replay older messages.
Learn more in Kafka Partition and Kafka Offset.
4. Topic Replication
Each partition of a topic can be copied to several brokers. The replication factor is set per topic: with a replication factor of 3, every partition has three copies on three different brokers. One copy is the leader; the others are followers that stay in sync. If the leader’s broker fails, a follower takes over.
Use a replication factor of 3 for important production topics, together with min.insync.replicas=2. See Kafka Fault Tolerance.
5. Naming Topics Well
Topic names can contain letters, digits, dots (.), underscores (_) and hyphens (-), up to 249 characters. Clear, consistent names make a cluster much easier to understand:
| Good name | Why |
|---|---|
shop.orders.created | Domain, entity and event are clear |
payments.payment-completed | Readable and specific |
inventory.stock-changed.v2 | Version suffix for a new, incompatible format |
- Pick one style for the whole organization, for example
domain.entity.event. - Avoid mixing dots and underscores in the same names: Kafka treats them as equal in metric names, so
my.topicandmy_topiccan collide. - Do not put changing details, such as team names or environments, in topic names if they may change; use separate clusters for environments.
6. Creating and Managing Topics with the CLI
# Create a topic with 6 partitions and 3 copies of each
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--create --topic shop.orders.created \
--partitions 6 --replication-factor 3 \
--config retention.ms=604800000 \
--config min.insync.replicas=2
# List all topics
bin/kafka-topics.sh --bootstrap-server localhost:9092 --list
# Show partitions, leaders, replicas and in-sync replicas
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --topic shop.orders.created
# Write a few test messages (type one per line, Ctrl+C to stop)
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 \
--topic shop.orders.created
# Read all messages from the beginning
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic shop.orders.created --from-beginning
604800000 milliseconds is 7 days. On a single-broker development setup, use --replication-factor 1, because a topic cannot have more copies than there are brokers.
7. Creating Topics with the Java Admin Client
Applications and setup tools can create topics with the Admin client, which is part of kafka-clients:
package com.example.kafka;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.common.errors.TopicExistsException;
public class TopicSetup {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
try (Admin admin = Admin.create(props)) {
NewTopic orders = new NewTopic("shop.orders.created", 6, (short) 3)
.configs(Map.of(
"retention.ms", "604800000", // 7 days
"min.insync.replicas", "2"));
try {
admin.createTopics(List.of(orders)).all().get();
System.out.println("Topic created");
} catch (ExecutionException e) {
if (e.getCause() instanceof TopicExistsException) {
System.out.println("Topic already exists");
} else {
throw e;
}
}
Set<String> names = admin.listTopics().names().get();
System.out.println("Topics: " + names);
}
}
}
8. Topics in Spring Boot
With Spring for Apache Kafka, declare topics as beans. At startup, Spring Boot’s KafkaAdmin creates any that do not exist yet:
package com.example.shop.config;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.common.config.TopicConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.TopicBuilder;
@Configuration
public class KafkaTopicsConfig {
@Bean
public NewTopic ordersCreated() {
return TopicBuilder.name("shop.orders.created")
.partitions(6)
.replicas(3)
.config(TopicConfig.RETENTION_MS_CONFIG, "604800000")
.config(TopicConfig.MIN_IN_SYNC_REPLICAS_CONFIG, "2")
.build();
}
@Bean
public NewTopic customerProfiles() {
// Keeps only the latest profile per customer ID
return TopicBuilder.name("shop.customers.profile")
.partitions(3)
.replicas(3)
.compact()
.build();
}
}
Spring does not delete or shrink existing topics. If a bean asks for more partitions than a topic has, Spring can add them; it never reduces them.
9. Writing to and Reading from a Topic
A producer writes to a topic by name, and a consumer subscribes to it by name:
@Service
class OrderEvents {
private final KafkaTemplate<String, String> kafka;
OrderEvents(KafkaTemplate<String, String> kafka) {
this.kafka = kafka;
}
void orderCreated(String orderId, String json) {
// The key (order ID) decides the partition, keeping one order's events in order
kafka.send("shop.orders.created", orderId, json);
}
}
@Component
class InventoryListener {
@KafkaListener(topics = "shop.orders.created", groupId = "inventory-service")
void onOrderCreated(ConsumerRecord<String, String> record) {
System.out.printf("partition=%d offset=%d key=%s%n",
record.partition(), record.offset(), record.key());
}
}
See Kafka Producer and Kafka Consumer for details.
10. Important Topic Settings
| Setting | Default | Meaning |
|---|---|---|
retention.ms | 604800000 (7 days) | How long messages are kept; -1 means forever |
retention.bytes | -1 (no limit) | Maximum size per partition before old data is deleted |
cleanup.policy | delete | delete, compact or compact,delete |
min.insync.replicas | 1 | In-sync copies required for acks=all writes; use 2 with replication factor 3 |
segment.bytes | 1 GB | Size of each log segment file |
max.message.bytes | About 1 MB | Largest allowed message batch |
compression.type | producer | Keep the producer’s compression, or force one such as zstd |
# Show a topic's settings
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name shop.orders.created --describe
# Change retention to 3 days while the topic is in use
bin/kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name shop.orders.created \
--alter --add-config retention.ms=259200000
11. Retention vs Log Compaction
| Delete (retention) | Compact | |
|---|---|---|
| Keeps | All messages, until they are older or larger than the limit | The latest message for each key |
| Removes | Whole old segments by time or size | Older messages that have a newer one with the same key |
| Good for | Event streams: orders, clicks, logs | Current state: customer profiles, account settings, prices |
| Deleting a key | Not possible individually | Send a message with that key and a null value (a “tombstone”) |
Before compaction:
[cust-1: Pune] [cust-2: Delhi] [cust-1: Mumbai] [cust-3: Goa] [cust-2: Jaipur]
After compaction:
[cust-1: Mumbai] [cust-3: Goa] [cust-2: Jaipur]
12. Choosing the Number of Partitions
The number of partitions limits how many consumers in one group can work in parallel, so plan for future growth:
partitions >= peak messages per second / messages per second one consumer can handle
Example: peak 6,000 msg/s, one consumer handles 1,000 msg/s -> at least 6 partitions
Add room for growth -> 12 partitions
- Many teams start with 3–12 partitions for normal topics.
- You can add partitions later, but not remove them.
- Adding partitions changes which partition each key maps to, so ordering by key is only guaranteed for new messages after the change.
- Avoid thousands of partitions per topic without a reason; each one uses broker resources.
13. Changing and Deleting Topics
# Increase partitions from 6 to 12 (cannot decrease)
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--alter --topic shop.orders.created --partitions 12
# Delete a topic (allowed by default: delete.topic.enable=true)
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--delete --topic shop.orders.test
- A topic cannot be renamed. Create a new topic and move producers and consumers to it.
- Changing the replication factor needs a partition reassignment with
kafka-reassign-partitions.sh. - Deleting a topic removes all its data permanently; make sure no application still needs it.
14. Internal Topics
| Internal topic | Purpose |
|---|---|
__consumer_offsets | Stores committed offsets of consumer groups |
__transaction_state | Stores the state of Kafka transactions |
__cluster_metadata | In KRaft mode, holds the cluster’s metadata log |
connect-configs, connect-offsets, connect-status | Used by Kafka Connect (names are configurable) |
Topics ending in -changelog or -repartition | Created by Kafka Streams applications |
Do not write to or delete these topics yourself. Make sure internal topics also have a replication factor of 3 in production.
15. Example: An Online Shopping Application
Imagine an online shop. When a customer places an order, the application sends an event to the topic shop.orders.created. Several services read it:
- Inventory service (group
inventory-service) updates stock. - Payment service (group
payment-service) processes the payment. - Notification service (group
notification-service) sends an email or SMS.
+--> inventory-service
Order Service --> shop.orders.created --+--> payment-service
+--> notification-service
All three read the same messages, each in its own consumer group, at its own speed. Producers do not need to know who reads the data, and consumers can join or leave at any time. That is why topics are the foundation of real-time, event-driven systems.
16. Best Practices
- Use a clear naming convention and document it.
- Create topics deliberately; disable automatic topic creation in production (
auto.create.topics.enable=false). - Use replication factor 3 and
min.insync.replicas=2for important topics. - Plan partition counts for future load.
- Set retention based on how long data might need to be replayed.
- Use compaction for “latest value per key” data.
- One kind of event per topic, or a clear, documented set of related events.
- Agree on message formats, ideally with schemas, and version breaking changes.
- Manage topics as code, for example with Spring
NewTopicbeans, Terraform or GitOps tools.
17. Common Mistakes to Avoid
| Mistake | What goes wrong | Better approach |
|---|---|---|
| Relying on automatic topic creation | Topics get default settings, often 1 partition and 1 copy | Create topics explicitly with the right settings |
| Too few partitions | Consumers cannot scale beyond the partition count | Plan for growth from the start |
| Replication factor 1 in production | A broker failure loses data | Use 3 |
| Retention too short | Consumers that fall behind lose data | Retain data longer than the longest expected outage |
| Expecting global ordering across partitions | Events arrive in a different order than sent | Use keys for ordering per entity |
| Inconsistent topic names | Hard to find and govern topics | Adopt one naming convention |
18. Summary
A Kafka topic is a named, append-only stream of related messages. Physically it is split into partitions, each an ordered log with offsets, replicated across brokers for safety. Topics decouple producers from consumers: producers write once, and any number of consumer groups read independently. Create topics deliberately with the CLI, the Java Admin client or Spring Boot beans; choose clear names, enough partitions and the right retention or compaction policy; and use replication factor 3 for important data. In simple terms, Kafka topics are organized data streams that help applications talk to each other efficiently, and they are the backbone of modern event-driven architectures.
19. Frequently Asked Questions (FAQ)
Q1. What is a Kafka topic in simple words?
A Kafka topic is a named channel for related messages, such as orders or page-views. Producers write messages to it, and consumers read from it.
Messages are kept in order and stored for a set time, so many applications can read the same topic independently.
Q2. What is the difference between a topic and a partition?
A topic is the logical name applications use. A partition is one physical, ordered piece of a topic. A topic with 6 partitions consists of 6 separate logs that can be stored on different brokers and read in parallel.
Q3. How do I create a Kafka topic?
With the command-line tool:
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--create --topic orders --partitions 6 --replication-factor 3
You can also use the Java Admin client, a Spring NewTopic bean, or infrastructure-as-code tools.
Q4. Are Kafka topics created automatically?
They can be. If auto.create.topics.enable=true, a topic is created the first time a client uses it, with the broker’s default partition count and replication factor.
This is handy in development but risky in production: a typo creates a new topic with possibly unsafe defaults. Most teams disable it and create topics explicitly.
Q5. How many partitions should a topic have?
Enough to handle your peak load in parallel, with room to grow. A simple rule is: peak messages per second divided by what one consumer can process per second. Many topics start with 3–12 partitions.
You can add partitions later but cannot remove them, and adding them changes how keys map to partitions.
Q6. Can I reduce the number of partitions of a topic?
No. Kafka only allows increasing the partition count. To have fewer partitions, create a new topic with the desired count, copy or re-produce the data, and move producers and consumers to it.
Q7. Can I rename a Kafka topic?
No. Kafka has no rename operation. Create a new topic, move producers to it, let consumers finish reading the old topic, switch them to the new one, and delete the old topic when it is no longer needed.
Q8. How long does a topic keep messages?
Seven days by default (retention.ms=604800000). You can set any duration, a size limit with retention.bytes, or keep data forever with retention.ms=-1. Reading messages does not delete them.
Q9. What is a compacted topic?
A compacted topic (cleanup.policy=compact) keeps at least the latest message for each key and removes older ones with the same key. It works like a changelog of current values, for example the latest address of every customer.
To delete a key completely, send a message with that key and a null value, called a tombstone.
Q10. Does a Kafka topic guarantee message order?
Only within each partition. Messages in one partition are always read in the order they were written. To keep related messages in order, give them the same key, so they go to the same partition.
Q11. Can multiple applications read the same topic?
Yes. Each application uses its own consumer group, and every group receives every message independently, at its own speed. Within one group, the partitions are shared among the group’s consumers.
Q12. Can one topic contain different types of events?
It can, but keep it deliberate. Putting related events for the same entity in one topic, such as OrderCreated, OrderPaid and OrderShipped, keeps them in order per order ID. Unrelated events are usually better in separate topics, so consumers only read what they need.
Q13. What replication factor should a topic use?
Use 3 for important production topics, with min.insync.replicas=2 and producers using acks=all. A single-broker development cluster can only use 1.
Q14. How do I see what is inside a topic?
Use the console consumer:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic orders --from-beginning --property print.key=true
Graphical tools such as Kafka UI, AKHQ or Kafdrop also let you browse topics and messages in a browser.
Q15. How do I delete a Kafka topic?
Use kafka-topics.sh --delete --topic <name>, or Admin.deleteTopics(...) in Java. Topic deletion is enabled by default (delete.topic.enable=true). All data is removed permanently, so check that no application still uses the topic.
Q16. Can I change topic settings after creation?
Yes, most settings, such as retention, cleanup policy and min.insync.replicas, can be changed at any time with kafka-configs.sh --alter or the Admin client, without restarting anything. Partitions can only be increased, and the replication factor is changed through partition reassignment.
Q17. What are topics starting with two underscores?
They are internal topics used by Kafka itself, such as __consumer_offsets for consumer offsets and __transaction_state for transactions. Do not write to or delete them.
Q18. Is there a limit on the number of topics?
There is no fixed limit on topics, but every partition uses broker memory, file handles and metadata. The practical limit is the total number of partitions in the cluster. KRaft-based clusters handle far more partitions than older ZooKeeper-based clusters, but it is still wise to avoid creating huge numbers of tiny topics.
Q19. What happens if a message is larger than the topic allows?
The broker rejects it with a RecordTooLargeException. The default limit is about 1 MB (max.message.bytes). You can raise it, but large messages hurt performance; a better pattern is to store large files elsewhere, such as object storage, and send only a reference in the message.
Q20. How should I name my Kafka topics?
Use one consistent pattern, for example domain.entity.event, such as shop.orders.created. Use lowercase, avoid mixing dots and underscores, and add a version suffix like .v2 for incompatible format changes.