systemdesign distributedsystem softwarearchitecture

Introduction

In Event Driven Architecture, and event is a record of something that happened.— a fact, in the past tense, that other parts of the system might care about.

Definition

An event is an immutable notification that a state change or significant occurrence took place in the system. It typically has:

  • What happened (e.g., OrderPlaced, UserSignedUp, PaymentFailed)
  • When it happened (a timestamp)
  • Relevant data/context (a payload — e.g., order ID, user ID, amount)
{
  "eventType": "OrderPlaced",
  "timestamp": "2026-06-25T10:32:00Z",
  "orderId": "abc123",
  "userId": "u456",
  "amount": 49.99
}

Characteristics

  • Immutable — once it happened, it happened; you don’t edit an event, you might emit a new one (e.g., OrderCancelled) to represent a later change.
  • Past tense / fact-based — an event describes something that already occurred, not a command to do something (that distinction matters — see below).
  • Self-contained — it usually carries enough data for consumers to act on it without needing to query back to the source system (though sometimes it’s just a lightweight pointer/ID, depending on design — “thin events” vs. “fat events”).
  • Decoupled — the producer doesn’t know (or care) who’s listening; consumers subscribe independently.

Event vs. Command vs. Message (important distinction)

TypeMeaningExample
CommandAn instruction telling something to do an actionPlaceOrder
EventA fact that something already happenedOrderPlaced
MessageThe generic envelope/container that carries either a command or an event(the Kafka record itself)

So a “message” is the transport-level term, while “event” specifically refers to the semantic meaning — a past occurrence.

SA01.4 - Event Driven Architecture > Event-Driven vs. Message-Driven Systems

Event Types

Notification Events

  • Minimal information
  • Less risk of data being out of sync
  • Consumers often need to fetch data
  • Increases architecture coupling (callback for info)
  • Producer/Consumer contracts kept minimum
  • Lower risk of breaking contracts

Event-Carried State Transfer

  • Enriched events (stateful) (Content Enricher Pattern)
  • Higher risk of data being out of sync
  • Consumers have the data
  • Decreases architecture coupling
  • Producer/consumer contracts more coupled
  • Higher risks of breaking contracts

Delta events

  • Stores difference between old/new
  • Examples seen in change data capture events
  • Can reduce complex in consumers needing to figure out what has changed

Domain Events

  • Events that raised in the same bounded context
  • Some folks reference these as internal events raised in bounded context
  • Some folks reference these as business “important” events.
  • People also refer to “integration” events. These are events used for integrations.

Internal vs External Events

Within a bounded context you can have many different services and communicate between these services using events, sometimes these are referred to as “private”, “internal” or “domain” events (depending on what you read…). These events belong within the bounded context, they can be exposed to implementation details and raise events assuming that downstream consumers understand the domain language used in the boundary and implementation details, they are “private” and not meant for “public” consumption.

Using events to communicate between bounded contexts (remember this can be within in your organization or outside your organization) can be referred to as “public” or “integration” events. Event contracts are important here, and ideally you do not want to expose private or implementation details of your domain in these. Consider a public language to communicate between systems (Defining a ubiquitous Language can help here).

Private/Internal Events

  • Can expose internal implementation details
  • Use a language that the domain understands, external domains may not understand this
  • Contract is important, but depending on how “close” the services are within boundary, could be relaxed?

Public/Integration Events

  • Should not really expose implementation details of the domain
  • Events use a language that is shared between the business or boundaries, no assumptions made
  • Contract is extremely important. Outside your domain you have less knowledge of who is consuming your events, don’t break them.