Blog
Wild & Free Tools

UUID in Microservices and Distributed Systems

Last updated: March 2026 6 min read
Quick Answer

Table of Contents

  1. Why Auto-Increment Fails in Microservices
  2. UUID Correlation IDs for Tracing
  3. UUID in Event Sourcing
  4. UUID for Database Sharding
  5. UUID v5 for Cross-Service References
  6. Frequently Asked Questions

Auto-increment IDs break in distributed systems. When three services independently write to three databases, who assigns the next integer? The answer requires a central coordinator — and central coordinators are bottlenecks. UUID generation requires no coordination: any service, any node, any time. This guide covers the patterns that make UUIDs effective in microservice architectures.

Why Auto-Increment IDs Break in Microservices

Auto-increment works by asking the database for the next integer in a sequence. In a single-database monolith, this is safe and fast. In a distributed system:

UUID v4 solves all of these: generated in memory, no network round trip, zero coordination, statistically guaranteed unique across all nodes.

UUID Correlation IDs — Trace a Request Across Services

When a user request touches 5 services, each service writes logs. Without a shared ID, you cannot connect those log entries. The pattern:

// API Gateway — assign correlation ID at entry:
const correlationId = req.headers['x-correlation-id'] || crypto.randomUUID();
req.headers['x-correlation-id'] = correlationId;

// Propagate to downstream services via HTTP header:
fetch('http://order-service/orders', {
  headers: { 'x-correlation-id': correlationId }
});

// Each service logs with the same ID:
logger.info('order created', { correlationId, orderId: order.id });

// Result: all log entries for one user request share a UUID —
// grep by UUID = complete request trace across all services

This is the basis of distributed tracing (OpenTelemetry, Jaeger, Zipkin). The trace ID is a UUID that threads through every service in the call graph.

Sell Custom Apparel — We Handle Printing & Free Shipping

UUID in Event Sourcing and Message Queues

// Event structure — every event gets a UUID:
{
  "eventId": "550e8400-e29b-41d4-a716-446655440000",   // unique per event
  "eventType": "OrderPlaced",
  "aggregateId": "a6edc906-2f9f-5fb2-a373-efac406f0ef2", // the order's UUID
  "correlationId": "...",                                // request trace
  "timestamp": "2026-04-14T12:00:00Z",
  "payload": { "productId": "...", "quantity": 1 }
}

// Consumer idempotency — check if event was already processed:
if (await eventStore.exists(event.eventId)) {
    // Already processed — skip, return cached result
    return;
}
await processEvent(event);
await eventStore.markProcessed(event.eventId);

The eventId is the idempotency key. Message queues (Kafka, SQS, RabbitMQ) can deliver messages more than once — the UUID lets consumers deduplicate without re-processing.

For time-ordered event logs, UUID v7 is better than v4 — events generated in sequence have UUIDs that sort in chronological order, making event replay and range queries much more efficient.

UUID for Database Sharding

When you shard a database by a primary key, auto-increment integers require a shard routing strategy that distributes IDs across shards — which means a central coordinator or pre-allocated ranges.

UUID sharding is simpler:

// Route by UUID prefix — first 4 chars of UUID = 65,536 possible values:
function getShard(uuid: string, shardCount: number): number {
    const prefix = parseInt(uuid.slice(0, 4), 16);
    return prefix % shardCount;
}

// Consistent: the same UUID always routes to the same shard.
// No central coordinator needed.
// Shard count can be increased by re-routing a subset of the range.

UUID v4 distributes uniformly across shards because it is random. UUID v7 clusters recent records on the same shard (because recent IDs share a time prefix) — this can cause hot shards. For sharded systems, v4 is often better than v7 for even distribution.

UUID v5 for Cross-Service Entity References

When two services independently need to reference the same entity, UUID v5 provides a way to derive a consistent UUID from a canonical identifier without synchronization:

// Both services agree on a namespace (a UUID v4 you generated once):
const PRODUCT_NAMESPACE = 'a8098c1a-f86e-11da-bd1a-00112444be1e';

// Service A (inventory) derives a UUID for product SKU-123:
const productId = uuidv5('SKU-123', PRODUCT_NAMESPACE);
// "d7c4e5f6-..."  — same every time

// Service B (orders) independently derives the same UUID:
const productId = uuidv5('SKU-123', PRODUCT_NAMESPACE);
// "d7c4e5f6-..."  — identical, no database lookup needed

// Both services reference the same entity by the same UUID
// without ever talking to each other or a shared registry.

This pattern is especially useful during migrations, when two systems need to share entity references before a proper integration is built.

Generate Correlation IDs and Event UUIDs

The Cheetah UUID Generator produces 1 or 10 RFC-compliant UUID v4 values — ready to paste into your event payloads, service configs, or test fixtures.

Open Free UUID Generator

Frequently Asked Questions

Why can't microservices use auto-increment IDs?

Auto-increment requires a central database sequence to generate the next integer. In a distributed system with multiple databases or services, there is no single source of truth for "the next integer" — UUIDs are generated locally without coordination.

What is the difference between a correlation ID and a trace ID?

They are often used interchangeably, but technically: a trace ID spans the entire request lifecycle; a span ID identifies one operation within the trace. Both are UUIDs. Correlation ID is a simpler term for the same concept in systems not using formal distributed tracing.

Should I use UUID v4 or v7 in microservices?

Use v4 for IDs that need to be opaque and evenly distributed (session tokens, correlation IDs, sharding keys). Use v7 for event IDs and database primary keys where time-ordering and sequential index insertion matter.

How does UUID prevent duplicate event processing in message queues?

Each event is assigned a UUID as its eventId. The consumer stores processed event IDs. Before processing, the consumer checks if the eventId has been seen — if yes, it skips the event. This makes the consumer idempotent against duplicate deliveries.

Can I use the same UUID as both a primary key and a correlation ID?

No — these are different things. A primary key identifies a resource permanently. A correlation ID identifies a single request/response cycle and is discarded after the request completes. Use separate UUIDs for each purpose.

Ryan Callahan
Ryan Callahan Lead Software Engineer

Ryan architected the client-side processing engine that powers every tool on WildandFree — ensuring your files never leave your browser.

More articles by Ryan →
Launch Your Own Clothing Brand — No Inventory, No Risk