Unique identifiers are fundamental to modern software systems.
Databases, APIs, microservices, and event-driven architectures all rely on them.
Most developers simply use random UUIDs. But at scale, randomness can introduce limitations.
This article introduces EUID (Evolutionary Unique Identifier) — a structured UUID v8 generator designed for distributed systems and database-friendly indexing.
The Problem With Traditional UUIDs
UUID v4
The most commonly used UUID is version 4, which is completely random.
While this guarantees uniqueness, it has several drawbacks in large systems:
• no time ordering
• poor database index locality
• opaque identifiers
• no infrastructure awareness
When UUID v4 values are used as database primary keys, inserts become effectively random, which can fragment indexes and reduce performance.
UUID v7
The newer UUID v7 specification introduces time ordering.
It includes:
• a 48-bit timestamp
• random entropy bits
This greatly improves database performance because records are inserted in roughly chronological order.
However, UUID v7 remains intentionally random beyond the timestamp.
In some distributed systems, it can be useful for identifiers to contain information about the infrastructure that generated them.
A Different Approach: Structured Identifiers
Instead of relying on randomness, some distributed systems prefer structured identifiers.
Examples include:
• snowflake-style identifiers
• sharded database IDs
• topology-aware identifiers
The core idea is simple:
An identifier can encode where it was generated, not just when.
This can help with:
• debugging distributed systems
• tracing requests
• understanding data origin
• operational observability
This philosophy inspired the design of EUID.
Introducing EUID
EUID (Evolutionary Unique Identifier) is a UUID v8-compatible identifier that combines:
• time ordering
• topology encoding
• deterministic generation
Unlike random UUIDs, EUID identifiers are fully decodable.
From a single identifier you can determine:
• when it was generated
• which region generated it
• which shard handled it
• which node created it
• the sequence number
EUID Bit Layout
EUID uses the 128-bit UUID structure with the following layout:
| Bits | Field |
|---|---|
| 48 | Timestamp (milliseconds) |
| 4 | Version (UUID v8) |
| 6 | Region |
| 6 | Shard |
| 2 | Variant |
| 14 | Node |
| 48 | Sequence |
Timestamp
A 48-bit millisecond timestamp ensures time ordering and database-friendly indexing.
Region / Shard / Node
These fields encode distributed topology, allowing identifiers to carry infrastructure metadata.
Sequence
Each node maintains a monotonic sequence counter to generate multiple identifiers within the same millisecond.
Operational Observability Through Identifiers
One interesting side effect of structured identifiers is operational observability.
In many systems, identifiers are opaque.
When something fails in production, engineers often need to query logs or databases just to determine where an identifier originated.
Because EUID embeds topology information directly in the identifier, operational metadata can be extracted immediately.
From a single identifier you can determine:
• when it was generated
• which region produced it
• which shard handled the request
• which node created the identifier
Instead of being black boxes, identifiers become structured infrastructure signals.
Example Usage
Generating an identifier in Java:
EuidGenerator generator = new EuidGenerator(1, 1, 1);
UUID id = generator.generate();
System.out.println("EUID: " + id);
Example output:
019caad2-a445-8083-8005-000000000011
The identifier can then be decoded:
DecodedEuid decoded = EuidDecoder.decode(id);
System.out.println(decoded.getInstant());
System.out.println(decoded.getRegion());
System.out.println(decoded.getShard());
System.out.println(decoded.getNode());
System.out.println(decoded.getSequence());
Base58 Encoding
EUID also supports Base58 encoding, which produces shorter and more human-friendly identifiers.
Example:
1CYctoRWaz5VGXwscmiovG
Base58 avoids visually confusing characters such as:
• 0 and O
• l and I
This makes identifiers easier to use in URLs, logs, and APIs.
When Should You Use EUID?
EUID can be useful when you need:
• time-ordered identifiers
• database-friendly indexing
• infrastructure-aware IDs
• deterministic identifier structure
If you only need a random identifier, UUID v4 or UUID v7 may already be sufficient.
EUID is designed for systems where traceability and infrastructure awareness are important.
Open Source Project
The EUID library is open source and available on Maven Central.
GitHub repository:
[https://github.com/louis-franck-moussima/euid-java]
The project includes:
• a high-performance generator
• Base58 encoding support
• full decode capability
• unit tests and stress tests
Conclusion
Identifiers are often treated as opaque random values.
But in distributed systems, identifiers can carry valuable structural information.
EUID explores an alternative approach using UUID v8 with deterministic topology encoding, producing identifiers that are:
• time ordered
• infrastructure aware
• database friendly
• fully decodable
If you are interested in the project, feel free to explore the repository or try the library in your own systems.
Feedback and discussion are always welcome you can leave questions in comments.
Top comments (0)