Skip to content

7 Message Metadata Patterns Every Developer Should Know

A message in message-driven systems consists of a payload (aka body) and metadata (aka headers). Message payload has application-specific data. Message metadata describes message payload and provides contextual information. It can also enable multiple message-based service communication patterns, solving common message-driven system challenges. Here are seven message metadata patterns every developer should know.

Message ID

Message ID helps with identifying individual messages. Each message has a unique ID attached to it. Adding message IDs is useful when building idempotent message consumers (read more about idempotence here). Moreover, it enables other metadata patterns, such as causation ID, which will be described later in this article.

Message ID

Causation ID

Causation ID identifies messages that cause other messages to be published. In simple terms, it's used to see what causes what. The first message in a message conversation typically doesn't have a causation ID. Downstream messages get their causation IDs by copying message IDs from messages, causing downstream messages to be published. Adding causation IDs is especially useful when different messages can cause the same message to be published, i.e., an order cancellation event might be published because a user has decided to cancel the order or because the user's credit card balance was insufficient.

Causation ID

Correlation ID

Correlation ID identifies messages that belong to the same message conversation. The ID is added to the first message and then passed to all downstream messages in the same transaction flow. Combine this pattern with a distributed tracing tool such as Zipkin or Jaeger, and you'll have a solid transaction monitoring and tracing setup.

Correlation ID

Reply Address

The reply address tells message consumers where to send reply messages. It enables request-reply communication in message-driven systems without strongly coupling message consumers with request message senders.

Reply address

Message Schema Version

Adding a message schema version helps to deploy breaking message schema changes without or with minimal service downtime. Moreover, publishing multiple versions of the same message for a limited amount of time is very useful when you can't change message consumers and publishers at the same time.

Message schema version

Message Sequence

Message sequence allows transferring an arbitrarily large amount of data using a messaging platform. Before publishing the data, message publishers split it into small chunks, each marked with a sequence number. Message consumers get the data by aggregating consumed messages following the message sequence in the order published.

Message sequence

There are other ways to send large files in message-driven systems. Read more about it here.

Message Expiration

Some messages are only relevant within a specified timeframe. In those cases, you should introduce message expiration. AMQP-based messaging platforms, more often than not, support message expiration out of the box. However, the same can't be said about stream-based messaging platforms. If you're using a stream-based messaging platform, adding a message expiration metadata field and discarding messages on the consumer's end will do the trick.

Message expiration


There are quite a few widely used message metadata patterns. They describe popular approaches to optimizing distributed messaging-based systems. You don't have to use all of them, but knowing about them is a significant advantage.

Thank you for reading. Do you know another pattern that this post needs to include? I would love to hear about it in the comments.