2.1 – Topics & Partitions Explained
What is a Kafka Topic?
A topic is a logical category or feed name to which messages are published.
Analogy:
- A topic is like a table in a database
- A topic is like a channel in a messaging system
- A topic is like a directory in a file system
Key Characteristics:
- Topics are named (e.g.,
orders,user-clicks,payments) - Topics are append-only (messages are added, never updated in-place)
- Topics are durable (messages are stored on disk for a configured retention period)
Topics as Logical Containers
Important: A topic is NOT a single file or queue. A topic is a logical grouping of one or more partitions.
Topic: "orders"
├── Partition 0
├── Partition 1
├── Partition 2
└── Partition 3
Key Point: The topic name is what producers and consumers use, but the actual data storage happens at the partition level.
What is a Partition?
A partition is a single, ordered, immutable sequence of messages (an append-only log).
Key Characteristics:
- Ordered: Messages within a partition have a total order (defined by offset)
- Immutable: Once written, messages cannot be changed
- Append-Only: New messages are always added to the end
- Parallelism Unit: Partitions enable parallel processing (one consumer per partition)
Partitions as Parallel Logs
Each partition is an independent log:
Topic: "orders" (3 partitions)
Partition 0:
┌───────┬───────┬───────┬───────┬───────┐
│ msg 0 │ msg 1 │ msg 2 │ msg 3 │ msg 4 │
└───────┴───────┴───────┴───────┴───────┘
Offsets: 0 1 2 3 4
Partition 1:
┌───────┬───────┬───────┬───────┐
│ msg 0 │ msg 1 │ msg 2 │ msg 3 │
└───────┴───────┴───────┴───────┘
Offsets: 0 1 2 3
Partition 2:
┌───────┬───────┬───────┬───────┬───────┬───────┐
│ msg 0 │ msg 1 │ msg 2 │ msg 3 │ msg 4 │ msg 5 │
└───────┴───────┴───────┴───────┴───────┴───────┘
Offsets: 0 1 2 3 4 5
Key Points:
- Each partition has its own offset sequence (starting from 0)
- Partitions can have different message counts (no requirement to be balanced)
- Messages in different partitions are independent (no ordering guarantee across partitions)
Ordering Guarantees (Critical Understanding)
1. Within a Partition: Total Order
Messages sent to the same partition are guaranteed to be ordered.
Example:
producer.send(new ProducerRecord<>("orders", "key-A", "msg-1"));
producer.send(new ProducerRecord<>("orders", "key-A", "msg-2"));
producer.send(new ProducerRecord<>("orders", "key-A", "msg-3"));
If all three messages go to partition 0:
- They will be stored in the order:
msg-1,msg-2,msg-3 - A consumer reading partition 0 will see them in that exact order
2. Across Partitions: No Order Guarantee
Messages in different partitions have no ordering relationship.
Example:
Partition 0: msg-A (timestamp: 10:00:01)
Partition 1: msg-B (timestamp: 10:00:00)
Partition 2: msg-C (timestamp: 10:00:02)
If a consumer reads all three partitions in parallel:
- It might see:
msg-B,msg-A,msg-C(not time-ordered) - It might see:
msg-A,msg-C,msg-B(not guaranteed)
Key Takeaway: If you need global ordering, use a single partition. If you need per-key ordering, use a keyed message (covered next).
Message Keys and Partition Assignment
Concept: Key → Partition Mapping
Kafka uses message keys to determine which partition a message goes to.
Two Scenarios:
Keyed Message (message has a key):
- Kafka computes
hash(key) % num_partitionsto determine partition - All messages with the same key go to the same partition
- Ordering is preserved per key
- Kafka computes
Non-Keyed Message (message key is
null):- Kafka uses round-robin or sticky partitioning
- No ordering guarantee
Example: Keyed Messages
Scenario: Track user actions per user.
Messages:
producer.send(new ProducerRecord<>("user-actions", "user-123", "login"));
producer.send(new ProducerRecord<>("user-actions", "user-456", "click"));
producer.send(new ProducerRecord<>("user-actions", "user-123", "purchase"));
Result (assuming 3 partitions):
hash("user-123") % 3 = 1 → Partition 1: [login, purchase]
hash("user-456") % 3 = 0 → Partition 0: [click]
Key Point: All actions for user-123 are in partition 1, so they are ordered. Actions for different users are in different partitions, so they can be processed in parallel.
Example: Non-Keyed Messages
Messages:
producer.send(new ProducerRecord<>("logs", null, "log-entry-1"));
producer.send(new ProducerRecord<>("logs", null, "log-entry-2"));
producer.send(new ProducerRecord<>("logs", null, "log-entry-3"));
Result (round-robin across 3 partitions):
Partition 0: log-entry-1
Partition 1: log-entry-2
Partition 2: log-entry-3
Key Point: No key = no ordering guarantee. Use this for high throughput when order doesn't matter.
Important: Partitioner is a Producer-Side Concept
Note: The logic that determines which partition a message goes to is called the partitioner. This is a producer-side mechanism.
Producer partitioner configs and custom partitioners are covered in M3: Kafka Producers.
What You Need to Know Here:
- Messages with the same key go to the same partition (by default)
- This enables per-key ordering
Partition Count Implications
The number of partitions in a topic has major implications for parallelism, throughput, and ordering.
1. Parallelism = Partition Count
Rule: You can have at most N consumers in a consumer group reading a topic with N partitions.
Example:
- Topic
ordershas 4 partitions - Consumer group
order-processorshas 4 consumers - Result: Each consumer reads 1 partition (maximum parallelism)
If you add a 5th consumer:
- It will be idle (no partition to assign)
Key Point: Partition count is the upper bound on consumer parallelism.
2. Throughput = Sum of Partition Throughput
Rule: Each partition can handle ~N MB/sec (limited by disk I/O, network, and CPU).
Example:
- One partition can handle ~10 MB/sec
- Topic with 10 partitions can handle ~100 MB/sec
Key Point: More partitions = higher throughput (up to broker capacity limits).
3. Ordering vs Parallelism Trade-off
| Partition Count | Ordering | Parallelism | Use Case |
|---|---|---|---|
| 1 partition | Global order (all messages) | Low (only 1 consumer) | Strict ordering required (e.g., bank account transactions) |
| N partitions (keyed) | Per-key order | High (N consumers) | Per-entity ordering (e.g., per-user, per-device) |
| N partitions (non-keyed) | No order | High (N consumers) | High throughput, order doesn't matter (e.g., logs) |
Key Takeaway: You cannot have both global ordering and high parallelism. You must choose.
4. Repartitioning is Expensive
Problem: Changing the partition count breaks key-to-partition assignment.
Example:
Original: 3 partitions
hash("user-123") % 3 = 1 → Partition 1
After adding partition (4 partitions):
hash("user-123") % 4 = 3 → Partition 3
Impact:
- Existing data stays in old partition (partition 1)
- New data goes to new partition (partition 3)
- Per-key ordering is broken (old messages in p1, new messages in p3)
Key Point: Always plan partition count upfront. Changing it later requires full topic rebalancing or data migration.
Partition Count Design Guidelines
How Many Partitions Should You Create?
General Formula:
Partitions = max(target_throughput / partition_throughput, max_consumers)
Example 1: Throughput-Driven:
- Target throughput: 100 MB/sec
- Per-partition throughput: 10 MB/sec
- Partitions needed: 100 / 10 = 10 partitions
Example 2: Consumer-Driven:
- You need 20 parallel consumers for fast processing
- Partitions needed: 20 partitions
Over-Partitioning vs Under-Partitioning
| Scenario | Problem | Solution |
|---|---|---|
| Under-Partitioned | Throughput bottleneck, not enough consumer parallelism | Increase partition count (requires topic recreation or partition expansion) |
| Over-Partitioned | Higher metadata overhead, slower leader elections, more memory usage | Use fewer partitions (but plan for future growth) |
Best Practice: Start with moderate partition count (e.g., 10-30 partitions) and scale up if needed.
Detailed partition sizing strategy is covered in Module 5.1: Designing Topics & Partition Strategy.
Topic and Partition Naming
Topic Naming Conventions
Best Practices:
- Use lowercase letters, numbers, hyphens, underscores (avoid special characters)
- Use descriptive names:
user-events,order-updates,payment-notifications - Use namespaces for multi-tenancy:
team-a.orders,team-b.orders
Avoid:
- Dots (
.) in topic names if using Kafka Streams (Streams uses dots for internal topics) - Very long names (> 249 characters, Kafka's limit)
Partition Naming (Internal)
On disk, partitions are stored as directories:
/var/lib/kafka-logs/
orders-0/
orders-1/
orders-2/
Format: <topic-name>-<partition-number>
Key Point: You don't manually name partitions. Kafka assigns partition numbers automatically (0, 1, 2, ...).
Replication and Partitions
Each partition can have multiple replicas (copies of the data).
Example:
Topic: "orders"
Partitions: 3
Replication Factor: 2
Partition 0:
- Leader: Broker 1
- Follower: Broker 2
Partition 1:
- Leader: Broker 2
- Follower: Broker 3
Partition 2:
- Leader: Broker 3
- Follower: Broker 1
Key Points:
- Replication factor determines how many copies of each partition exist
- Leader replica handles all reads and writes
- Follower replicas replicate data from the leader (for fault tolerance)
Deep replication mechanics are covered in Module 3.1: Replication & Fault Tolerance.
Topic Metadata
When you create a topic, Kafka stores metadata about it:
| Metadata | Description |
|---|---|
| Topic Name | orders |
| Partition Count | 10 |
| Replication Factor | 3 |
| Partition Leaders | {p0: broker-1, p1: broker-2, ...} |
| ISR (In-Sync Replicas) | List of replicas that are up-to-date |
| Topic Configs | Retention, compaction, max message size, etc. |
Clients fetch metadata to know:
- Which broker hosts the leader for partition X?
- How many partitions does the topic have?
Metadata Flow:
Producer Any Broker
│ │
├──Metadata Request─────────▶│
│ (topic: orders) │
│ │
│◀──Metadata Response─────────┤
│ { │
│ partitions: 3, │
│ p0: leader=broker-1, │
│ p1: leader=broker-2, │
│ p2: leader=broker-3 │
│ } │
Key Point: Clients cache metadata locally and refresh it periodically (or when they get errors indicating metadata is stale).
Key Takeaways
Topic = Logical Category: A topic is a named feed (e.g.,
orders). It's made up of one or more partitions.Partition = Ordered Log: Each partition is an independent, append-only, ordered log of messages.
Ordering Guarantee: Messages within a partition are totally ordered. Messages across partitions are not ordered.
Message Keys: Messages with the same key go to the same partition, enabling per-key ordering.
Partition Count = Parallelism Limit: You can have at most N consumers reading a topic with N partitions.
Repartitioning is Hard: Changing partition count breaks key-to-partition mapping. Plan partition count upfront.
Replication Factor: Each partition can have multiple replicas for fault tolerance (one leader, N followers).
What's Next?
Next Module: 2.2 – Log Structure & Message Storage
What We Covered:
- ✅ Topics as logical containers
- ✅ Partitions as parallel, ordered logs
- ✅ Ordering guarantees (within partition vs across partitions)
- ✅ Message keys and partition assignment
- ✅ Partition count implications (parallelism, throughput, ordering)
- ✅ Topic metadata
What We Didn't Cover (Explicitly Deferred):
- ❌ Producer partitioner configs → M3: Kafka Producers
- ❌ Consumer group partition assignment → M4: Kafka Consumers
- ❌ Deep replication protocol → Module 3.1 & M7: Internals
- ❌ Partition sizing strategy → Module 5.1
Topics & Partitions: Complete ✅