// thin
{ "type": "CustomerUpdated", "customerId": "c-91" }
// fat
{ "type": "CustomerUpdated", "customerId": "c-91",
"name": "Ana Silva", "email": "ana@example.com", "tier": "gold" }
A thin event carries only ids. A fat event carries the data consumers need.
Thin event (notification). It says that something happened and carries little more than ids. A consumer that needs details calls the service that owns the data.
Pros:
- The event is small.
- It never contains stale (old) data.
Cons:
- Every consumer adds load on the owning service.
- Consumers depend on the owner being up.
- The data they fetch may already be newer than the event.
Fat event (event-carried state transfer). It carries the state that consumers need. Consumers can keep a local copy of the data. They keep working while the owner is down, and they never need to call back.
Cons:
- Messages are bigger.
- The same data is copied across many services.
- The schema contract is larger and harder to change.
- You must be careful with sensitive fields, such as personal data.
When to choose each:
- Use thin events when consumers need fresh data, or when only a few consumers need details.
- Use fat events when many consumers need the data, when availability and decoupling matter, or when you build read models (local copies shaped for queries).
A common middle ground is to include only the fields that changed.
- A thin event carries only ids, and consumers call back for details.
- Thin events add load on the owner and make consumers depend on it at runtime.
- A fat event carries state, so consumers keep local copies and stay independent.
- Fat events cost bigger messages, duplicated data and a bigger contract.
- Choose based on how fresh the data must be, how many consumers there are, and how much coupling you accept.
Read more