Anatomy of an event
An event has two parts: an envelope of metadata that every event carries in the same shape, and a payload with the business facts of this one event. The envelope lets infrastructure route, deduplicate and trace messages without understanding what is inside them.
In code
public sealed record EventEnvelope<T>( Guid MessageId, string MessageType, DateTimeOffset OccurredOn, int Version, Guid CorrelationId, Guid? CausationId, T Payload); public sealed record OrderLine(string Sku, int Quantity); public sealed record OrderPlaced( Guid OrderId, Guid CustomerId, decimal Total, IReadOnlyList<OrderLine> Lines); var placed = new EventEnvelope<OrderPlaced>( MessageId: Guid.NewGuid(), MessageType: "OrderPlaced", OccurredOn: DateTimeOffset.UtcNow, Version: 1, CorrelationId: checkoutId, CausationId: null, Payload: new OrderPlaced(orderId, customerId, 59.90m, lines));The envelope
MessageIdidentifies this one message. Consumers use it to spot a duplicate, see idempotent consumersIdempotent consumersA consumer that gives the same result whether a message arrives once or five times.Opens in a new tab.MessageTypenames the event, such asOrderPlaced. Routing and deserialization start from it.OccurredOnis when the thing happened, which can differ from when the message was sent.Versionis the version of the payload shape, so consumers can cope with change, see event versioningEvent versioningChange an event's shape by adding to it, and run a second version beside the first when you must break it.Opens in a new tab.CorrelationIdis shared by every message that belongs to one original request, here the whole checkout.CausationIdis theMessageIdof the message that directly caused this one. Together with the correlation id it lets a trace be rebuilt, see observing event flowsObserving event flowsFollowing one order through several services, and the three queue numbers that warn first.Opens in a new tab.
The CloudEventsA vendor-neutral specification for describing event data. specification standardizes a similar envelope. It requires id, source, specversion and type, and defines optional attributes such as time, subject and datacontenttype. The names differ from the record above, but the roles match, so there is no need to invent a format when a standard exists.
The payload
The payload carries what consumers need about the fact. OrderPlaced holds the order id, the customer, the total and the lines. How much to put in is a real choice: a small event with only ids makes consumers ask back for details, a large one copies data into every consumer. See event notification vs state transferEvent notification vs state transferA thin event says that something happened. A fat event also carries the data.Opens in a new tab.
The catch
Every subscriber can read the whole event. Events are often visible to components that do not need them, so personal data, secrets and card details do not belong in the payload. Microsoft’s guide recommends thinking about what an event exposes with an assume-breach mindset.
Sources
- CloudEvents Specification v1.0.2, CloudEvents · accessed June 12, 2026
- Event-Driven Architecture Style, Azure Architecture Center, Microsoft Learn · accessed June 12, 2026
- What do you mean by Event-Driven?, martinfowler.com · accessed June 12, 2026