Apache Kafka stores messages as key-value pairs. The key determines partition assignment and enables log compaction — Kafka retains only the last message per key when compaction is enabled. UUID v4 keys are stateless and collision-safe but carry no ordering information. UUID v7 adds a 48-bit millisecond timestamp to every key, enabling time-range replay, deduplication by recency, and approximate ordering within a partition — all without any schema changes. The Apache Kafka documentation and the uuid npm package (for Node.js producers) both support the patterns described here.

Why message key choice matters

Kafka routes messages to partitions by hashing the key. The key also drives:

UUID v7 for event ordering

UUID v4 keys provide no ordering within a partition. UUID v7 keys are lexicographically ordered by creation time:

Event 1: 019236a7-b4f2-7000-8d3e-9c1a2b3d4e5f  (t = 1727308800000 ms)
Event 2: 019236a7-b4f4-7000-8e2f-7b4c5d6e7f80  (t = 1727308800002 ms)
Event 3: 019236a7-b4f6-7000-9a1b-6c5d4e3f2a91  (t = 1727308800004 ms)

Sorting these keys as strings gives the correct production sequence. A Kafka Streams application can use this to reconstruct event timelines without a separate timestamp field.

Time-range replay

Standard Kafka replay requires knowing the partition offset for a target time. With UUID v7 keys, you can binary-search the key space by timestamp prefix:

// Java: find the offset for events after a target time
long targetMs = Instant.parse("2026-09-01T00:00:00Z").toEpochMilli();
String targetPrefix = String.format("%012x", targetMs); // 48-bit hex prefix

// Compare UUIDs: event.key().startsWith(targetPrefix or greater)

This works because UUID v7 keys sort the same way timestamps sort — a property guaranteed by RFC 9562 §5.7.

Producer configuration (Java)

ProducerRecord<String, byte[]> record = new ProducerRecord<>(
    "orders",
    UuidCreator.getTimeOrderedEpoch().toString(), // UUID v7 key
    orderPayload
);
producer.send(record);

The uuid-creator Java library provides getTimeOrderedEpoch() which generates RFC 9562-compliant UUID v7.

Producer configuration (Python)

from uuid6 import uuid7
from confluent_kafka import Producer

producer = Producer({'bootstrap.servers': 'localhost:9092'})
producer.produce(
    'orders',
    key=str(uuid7()),   # UUID v7 string key
    value=payload_bytes
)

The uuid6 package on PyPI implements UUID v7 for Python producers.

Partition skew consideration

UUID v7 keys generated in rapid bursts share the same millisecond prefix. Kafka’s default murmur2 hash distributes them differently from purely random UUIDs — high-burst producers may see temporary partition skew. Mitigations:

Log compaction with UUID v7 entity keys

For entity changelog topics (one key per entity, latest value wins):

Topic: user-profile-changes
Key: <user UUID v7, assigned at account creation>
Value: serialised user state

Using UUID v7 as the entity key means the key itself encodes when the entity was created — useful for auditing and for filtering compacted topics by cohort (all users created in January 2026 share a key prefix).

Further reading

External references

Frequently asked questions

Why use UUID v7 instead of UUID v4 as a Kafka message key?

UUID v4 keys distribute messages uniformly across partitions, which is good for load balancing but loses time ordering. UUID v7 keys preserve millisecond-precision ordering within a partition — consumers can process events in creation sequence without a separate event_time field. The embedded timestamp also enables time-range replay: seek to the partition offset corresponding to a target time by binary-searching the UUID key prefix. See RFC 9562 §5.7 for the UUID v7 bit layout.

How do I extract the timestamp from a UUID v7 Kafka key?

In Java (Kafka Streams or consumer): long ms = Long.parseUnsignedLong(key.replace("-","").substring(0,12), 16);. In Python with uuid6 on PyPI: uuid6.UUID(key).time returns Unix milliseconds. The first 12 hex characters encode the 48-bit timestamp defined in RFC 9562.

Does UUID v7 affect Kafka partition assignment?

Yes. Kafka's default partitioner hashes the message key to select a partition. UUID v7 keys have a shared time-prefix for bursts of events in the same millisecond, which could skew partitioning if events cluster in time. Use a custom partitioner that hashes the full 128-bit value, or include a producer ID suffix — the Apache Kafka documentation covers custom partitioner configuration via partitioner.class.