DEV Community

Cover image for Designing a Structured UUID v8 Generator for Distributed Systems (EUID)
Louis Franck M
Louis Franck M

Posted on

Designing a Structured UUID v8 Generator for Distributed Systems (EUID)

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);
Enter fullscreen mode Exit fullscreen mode

Example output:

019caad2-a445-8083-8005-000000000011
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

Base58 Encoding

EUID also supports Base58 encoding, which produces shorter and more human-friendly identifiers.

Example:

1CYctoRWaz5VGXwscmiovG
Enter fullscreen mode Exit fullscreen mode

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)