Skip to main content

Correlation ID

The Correlation ID pattern tags each request with a unique identifier and propagates it through every service, log, and downstream call, so related events can be tied together with one search. It is a cheap operability baseline that underpins log aggregation and complements distributed tracing.

Type
Resilience
When to Use
Log Correlation, Distributed Debugging, Cross Service Flows, Request Tracking

When a request fails somewhere inside a distributed system, an engineer must reconstruct what happened across many services, each writing its own logs. Without a shared identifier, correlating those logs is guesswork based on timestamps and luck. The Correlation ID pattern fixes this: a unique ID is assigned to each incoming request and carried through every service, log line, and downstream call it touches, so all events belonging to one request can be found by a single search.

How It Works

At the system edge (an API gateway or the first service), each request is checked for an existing correlation ID header (e.g. X-Correlation-ID or X-Request-ID). If present, it is reused; if not, a new unique ID (typically a UUID) is generated. From then on:

  • The ID is propagated in headers on every downstream HTTP/RPC call and in message metadata on every queue publish.
  • It is attached to every log entry, usually via a logging context (MDC in Java, context variables, structured-logging fields) so developers do not pass it manually.
  • It is often returned to the client in the response, so a user's support ticket can reference the exact request.

Searching logs (typically in an aggregation system) for one correlation ID then surfaces the complete cross-service story of that request.

When to Use It

Use correlation IDs in any multi-service or asynchronous system: microservices, event-driven pipelines, and serverless workflows. They are a near-mandatory baseline for operability — far cheaper to add than full tracing and immediately valuable for debugging, support, and audit. Even a single service benefits, since one logical request may span multiple log lines.

Trade-offs

The ID is only useful if propagated everywhere; one service that drops it breaks the chain, so propagation must be consistent (often enforced via shared middleware or a sidecar). It adds a small amount of plumbing and discipline. A correlation ID gives you searchable grouping but, unlike full distributed tracing, no automatic timing or parent/child structure — many teams adopt both, using the trace ID as the correlation ID.

Related Patterns

Correlation ID is the foundation beneath distributed-tracing (which adds timing and span hierarchy), is what makes log-aggregation searchable across services, and is commonly injected by the sidecar-pattern in a service mesh.

Example

Middleware that ensures and propagates the ID:

id = request.header("X-Correlation-ID") or uuid()
logContext.put("correlationId", id)        // every log line tagged
outgoingHeaders["X-Correlation-ID"] = id   // propagate downstream
response.header("X-Correlation-ID", id)    // return to caller

One search for that ID reveals every log line the request produced, across all services.