# Event / Messaging / Asynchronous Architecture

> Every principle in this category is listed as a record.

Page: Ontology · Principles
Canonical: https://banes-lab.com/ontology#architecture-category-event-messaging-asynchronous-architecture

Listed in [Ontology · Principles](https://banes-lab.com/api/pages/ontology/principles.md), after [SOLID / Object-Oriented Design](https://banes-lab.com/ontology/principles/architecture-category-solid-object-oriented-design.md) and before [Error Handling / Resilience](https://banes-lab.com/ontology/principles/architecture-category-error-handling-resilience.md).

Every principle in this category is listed as a record. Each record carries its kind, its severity, the scopes it applies at and the layer it lives in, then the edge relations that join it to other records, the records that point back at it, the contracts that answer to it and the tensions it takes part in. The descriptors say how it is violated, detected, measured, repaired and enforced. Where the record carries one, an exemplar shows the shape before and after the principle is applied.

Relations diagram

The relations inside this category.

```mermaid
flowchart LR
n_event_driven_architecture["Event-Driven Architecture"]
n_publish_subscribe_pattern["Publish/Subscribe Pattern"]
n_message_queue["Message Queue"]
n_message_broker["Message Broker"]
n_event_bus["Event Bus"]
n_event_stream["Event Stream"]
n_event_sourcing["Event Sourcing"]
n_command_query_responsibility_segregation["CQRS"]
n_domain_events["Domain Events"]
n_integration_events["Integration Events"]
n_asynchronous_communication["Asynchronous Communication"]
n_eventual_consistency["Eventual Consistency"]
n_saga_pattern["Saga Pattern"]
n_outbox_pattern["Outbox Pattern"]
n_compensating_transaction["Compensating Transaction"]
n_append_only_log["Append-Only Log"]
n_dead_letter_queue["Dead-Letter Queue"]
n_idempotent_consumer["Idempotent Consumer"]
n_competing_consumers["Competing Consumers"]
n_event_driven_architecture --> n_asynchronous_communication
n_event_driven_architecture --> n_event_sourcing
n_event_driven_architecture --> n_command_query_responsibility_segregation
n_event_bus --> n_event_driven_architecture
n_event_sourcing --> n_append_only_log
n_event_sourcing --> n_domain_events
n_command_query_responsibility_segregation --> n_event_sourcing
n_command_query_responsibility_segregation -.-> n_eventual_consistency
n_domain_events --> n_event_driven_architecture
n_asynchronous_communication --> n_event_driven_architecture
n_saga_pattern --> n_eventual_consistency
n_compensating_transaction --> n_saga_pattern
n_append_only_log --> n_event_sourcing
n_dead_letter_queue --> n_message_queue
n_idempotent_consumer --> n_eventual_consistency
n_competing_consumers --> n_message_queue
```

### Event-Driven Architecture

- Kind: [style](https://banes-lab.com/records/kind/style.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: service, integration, system
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A convention of connecting services through published events, with each consumer reacting independently of the producer.

Requires
[Events](https://banes-lab.com/records/lexicon/events.md), [Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Idempotency](https://banes-lab.com/records/architecture/idempotency.md)

Reinforces
[Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md)

Enables
[Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md), [CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md), [Saga](https://banes-lab.com/records/lexicon/saga.md)

In tension with
[Debuggability](https://banes-lab.com/records/lexicon/debuggability.md), [Strong Consistency](https://banes-lab.com/records/lexicon/strong-consistency.md)

Conflicts with
[Hidden Temporal Coupling](https://banes-lab.com/records/lexicon/hidden-temporal-coupling.md)

Referenced by
[Choreography](https://banes-lab.com/records/architecture/choreography.md), [Event Bus](https://banes-lab.com/records/architecture/event-bus.md), [Domain Events](https://banes-lab.com/records/architecture/domain-events.md), [Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md), [Observer Pattern](https://banes-lab.com/records/architecture/observer-pattern.md), [Idempotency](https://banes-lab.com/records/architecture/idempotency.md)

Tensions
[Event-Driven Architecture / Debuggability](https://banes-lab.com/records/tension/debuggability-event-driven-architecture.md), [Event-Driven Architecture / Strong Consistency](https://banes-lab.com/records/tension/event-driven-architecture-strong-consistency.md)

Violated by
non-idempotent consumers, undocumented event schemas

Detected by
missing correlation IDs, direct synchronous chains

Measured by
event contract coverage, [retry safety](https://banes-lab.com/records/lexicon/retry-safety.md)

Refactored by
Publish Event, Add Outbox, Add Consumer Contract

Enforced by
schema registry, idempotency tests

Before

```typescript
async function createFoo(foo: Foo) {
await fooStore.save(foo);
await barService.refresh(foo.id);
await bazService.notify(foo.id);
}
```

After

```typescript
async function createFoo(foo: Foo) {
await fooStore.save(foo);
await events.publish({ type: "FooCreated", fooId: foo.id });
}
events.on("FooCreated", updateBarProjection);
events.on("FooCreated", notifyBaz);
```

How it is checked

Checked by
schema registry, idempotency tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Events](https://banes-lab.com/records/lexicon/events.md), [Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Idempotency](https://banes-lab.com/records/architecture/idempotency.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md), [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md), [CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md), [Saga](https://banes-lab.com/records/lexicon/saga.md)

Shape it refuses
[Hidden Temporal Coupling](https://banes-lab.com/records/lexicon/hidden-temporal-coupling.md)

### Publish/Subscribe Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: integration, eventing
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern in which publishers send messages to a topic and every subscriber to that topic receives them.

Requires
[Publisher](https://banes-lab.com/records/lexicon/publisher.md), [Subscriber](https://banes-lab.com/records/lexicon/subscriber.md), [Broker/Event Bus](https://banes-lab.com/records/lexicon/broker-event-bus.md)

Reinforces
[Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)

Enables
[Fan-Out Notification](https://banes-lab.com/records/lexicon/fan-out-notification.md)

In tension with
[Delivery Ordering](https://banes-lab.com/records/lexicon/delivery-ordering.md)

Conflicts with
[Direct Point-to-Point Calls](https://banes-lab.com/records/lexicon/direct-point-to-point-calls.md)

Tensions
[Publish/Subscribe Pattern / Delivery Ordering](https://banes-lab.com/records/tension/delivery-ordering-publish-subscribe-pattern.md)

Violated by
publisher knowing all subscribers

Detected by
direct calls to subscriber list

Measured by
publisher-subscriber coupling

Refactored by
Introduce Topic/Event Bus

Enforced by
messaging contracts

Before

```typescript
function saveFoo(foo: Foo) {
fooStore.save(foo);
auditFoo(foo);
indexFoo(foo);
}
```

After

```typescript
publisher.publish("foo.saved", { fooId: foo.id });
subscriber.on("foo.saved", auditFoo);
subscriber.on("foo.saved", indexFoo);
```

How it is checked

Checked by
messaging contracts

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Publisher](https://banes-lab.com/records/lexicon/publisher.md), [Subscriber](https://banes-lab.com/records/lexicon/subscriber.md), [Broker/Event Bus](https://banes-lab.com/records/lexicon/broker-event-bus.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Fan-Out Notification](https://banes-lab.com/records/lexicon/fan-out-notification.md)

Shape it refuses
[Direct Point-to-Point Calls](https://banes-lab.com/records/lexicon/direct-point-to-point-calls.md)

### Message Queue

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: integration, async processing
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A mechanism that holds messages durably until a consumer takes and acknowledges each one.

Requires
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Consumer](https://banes-lab.com/records/lexicon/consumer.md)

Reinforces
[Resilience](https://banes-lab.com/records/architecture/resilience.md), [Backpressure](https://banes-lab.com/records/architecture/backpressure.md)

Enables
[Asynchronous Processing](https://banes-lab.com/records/lexicon/asynchronous-processing.md)

In tension with
[Latency](https://banes-lab.com/records/architecture/latency.md)

Conflicts with
[In-Memory Direct Invocation](https://banes-lab.com/records/lexicon/in-memory-direct-invocation.md)

Referenced by
[Dead-Letter Queue](https://banes-lab.com/records/architecture/dead-letter-queue.md), [Competing Consumers](https://banes-lab.com/records/architecture/competing-consumers.md)

Tensions
[Message Queue / Latency](https://banes-lab.com/records/tension/latency-message-queue.md)

Distinct from
[Consumer](https://banes-lab.com/records/lexicon/consumer.md): A message queue holds messages until they are acknowledged, while the consumer is the component that takes and processes them.

Violated by
unbounded in-memory work queues

Detected by
synchronous blocking chains for async work

Measured by
queue depth, retry/dead-letter rates

Refactored by
Introduce Queue, Add Worker

Enforced by
infrastructure policy, load tests

Before

```typescript
for (const foo of foos) await processFoo(foo);
```

After

```typescript
for (const foo of foos) await fooQueue.enqueue({ type: "ProcessFoo", foo });
fooWorker.consume(fooQueue, message => processFoo(message.foo));
```

How it is checked

Checked by
infrastructure policy, load tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Consumer](https://banes-lab.com/records/lexicon/consumer.md), [Resilience](https://banes-lab.com/records/architecture/resilience.md), [Backpressure](https://banes-lab.com/records/architecture/backpressure.md), [Asynchronous Processing](https://banes-lab.com/records/lexicon/asynchronous-processing.md)

Shape it refuses
[In-Memory Direct Invocation](https://banes-lab.com/records/lexicon/in-memory-direct-invocation.md)

### Message Broker

- Kind: [artifact](https://banes-lab.com/records/kind/artifact.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: integration, messaging
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
Descriptive data about topics, queues and routing rules, held by an intermediary service that delivers messages between producers and consumers.

Requires
[Message Queue/Topics](https://banes-lab.com/records/lexicon/message-queue-topics.md), [Routing](https://banes-lab.com/records/lexicon/routing.md)

Reinforces
[Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Scalability](https://banes-lab.com/records/architecture/scalability.md)

Enables
[Pub/Sub](https://banes-lab.com/records/lexicon/pub-sub.md), [Work Distribution](https://banes-lab.com/records/lexicon/work-distribution.md)

In tension with
[Operational Dependency](https://banes-lab.com/records/lexicon/operational-dependency.md)

Conflicts with
[Point-to-Point Coupling](https://banes-lab.com/records/lexicon/point-to-point-coupling.md)

Tensions
[Message Broker / Operational Dependency](https://banes-lab.com/records/tension/message-broker-operational-dependency.md)

Violated by
broker bypass for async integration

Detected by
direct service calls in async workflows

Measured by
broker usage coverage

Refactored by
Add Broker, Route Messages

Enforced by
architecture policy

Before

```typescript
await fooService.sendToBar(barMessage);
await fooService.sendToBaz(bazMessage);
```

After

```typescript
await broker.publish("foo.created", fooMessage, { durable: true });
broker.subscribe("foo.created", { group: "bar-consumer", ack: "manual" }, handleBar);
broker.subscribe("foo.created", { group: "baz-consumer", ack: "manual" }, handleBaz);
```

How it is checked

Checked by
architecture policy

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Queue/Topics](https://banes-lab.com/records/lexicon/message-queue-topics.md), [Routing](https://banes-lab.com/records/lexicon/routing.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Scalability](https://banes-lab.com/records/architecture/scalability.md), [Pub/Sub](https://banes-lab.com/records/lexicon/pub-sub.md), [Work Distribution](https://banes-lab.com/records/lexicon/work-distribution.md)

Shape it refuses
[Point-to-Point Coupling](https://banes-lab.com/records/lexicon/point-to-point-coupling.md)

### Event Bus

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: application, integration
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A mechanism that dispatches each emitted event to the handlers registered for its type.

Requires
[Event Contract](https://banes-lab.com/records/lexicon/event-contract.md), [Subscriber Model](https://banes-lab.com/records/lexicon/subscriber-model.md)

Reinforces
[Pub/Sub](https://banes-lab.com/records/lexicon/pub-sub.md), [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

Enables
[Decoupled Event Distribution](https://banes-lab.com/records/lexicon/decoupled-event-distribution.md)

In tension with
[Event Storm / Traceability](https://banes-lab.com/records/lexicon/event-storm-traceability.md)

Conflicts with
[Direct Event Handler Calls](https://banes-lab.com/records/lexicon/direct-event-handler-calls.md)

Tensions
[Event Bus / Event Storm / Traceability](https://banes-lab.com/records/tension/event-bus-event-storm-traceability.md)

Violated by
hidden implicit event dependencies

Detected by
undocumented subscribers

Measured by
event dependency visibility

Refactored by
Introduce Event Bus, Register Handlers

Enforced by
handler registry validation

Before

```typescript
fooEditor.onSave = foo => fooView.refresh(foo);
fooEditor.onDelete = id => fooView.remove(id);
```

After

```typescript
eventBus.emit({ type: "FooSaved", foo });
eventBus.emit({ type: "FooDeleted", fooId: id });
eventBus.on("FooSaved", event => fooView.refresh(event.foo));
```

How it is checked

Checked by
handler registry validation

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Event Contract](https://banes-lab.com/records/lexicon/event-contract.md), [Subscriber Model](https://banes-lab.com/records/lexicon/subscriber-model.md), [Pub/Sub](https://banes-lab.com/records/lexicon/pub-sub.md), [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md), [Decoupled Event Distribution](https://banes-lab.com/records/lexicon/decoupled-event-distribution.md)

Shape it refuses
[Direct Event Handler Calls](https://banes-lab.com/records/lexicon/direct-event-handler-calls.md)

### Event Stream

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: stream processing, integration
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A mechanism that keeps events in an ordered, replayable log that consumers read from their own offset.

Requires
[Ordered Log](https://banes-lab.com/records/lexicon/ordered-log.md), [Event Schema](https://banes-lab.com/records/lexicon/event-schema.md)

Reinforces
[Streaming Architecture](https://banes-lab.com/records/architecture/streaming-architecture.md)

Enables
[Replay](https://banes-lab.com/records/lexicon/replay.md), [Continuous Processing](https://banes-lab.com/records/lexicon/continuous-processing.md)

In tension with
[Storage Volume](https://banes-lab.com/records/lexicon/storage-volume.md)

Conflicts with
[Mutable State Only](https://banes-lab.com/records/lexicon/mutable-state-only.md)

Referenced by
[Streaming Architecture](https://banes-lab.com/records/architecture/streaming-architecture.md)

Tensions
[Event Stream / Storage Volume](https://banes-lab.com/records/tension/event-stream-storage-volume.md)

Violated by
non-replayable event processing

Detected by
missing offsets, missing event schema

Measured by
replay success, lag

Refactored by
Add Stream, Add Offset Tracking

Enforced by
stream contract tests

Before

```typescript
const latest = await fooApi.getCurrentState(fooId);
```

After

```typescript
const stream = fooEvents.stream(fooId);
for await (const event of stream) fooProjection.apply(event);
```

How it is checked

Checked by
stream contract tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Ordered Log](https://banes-lab.com/records/lexicon/ordered-log.md), [Event Schema](https://banes-lab.com/records/lexicon/event-schema.md), [Streaming Architecture](https://banes-lab.com/records/architecture/streaming-architecture.md), [Replay](https://banes-lab.com/records/lexicon/replay.md), [Continuous Processing](https://banes-lab.com/records/lexicon/continuous-processing.md)

Shape it refuses
[Mutable State Only](https://banes-lab.com/records/lexicon/mutable-state-only.md)

### Event Sourcing

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: domain, persistence
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that stores state as the sequence of events that produced it and rebuilds current state by replaying them.

Requires
[Append-Only Log](https://banes-lab.com/records/architecture/append-only-log.md), [Domain Events](https://banes-lab.com/records/architecture/domain-events.md)

Reinforces
[Auditability](https://banes-lab.com/records/architecture/auditability.md), [Temporal Modeling](https://banes-lab.com/records/lexicon/temporal-modeling.md)

Enables
[Replay](https://banes-lab.com/records/lexicon/replay.md), [Replay](https://banes-lab.com/records/lexicon/replay.md)

In tension with
[Query Complexity](https://banes-lab.com/records/lexicon/query-complexity.md)

Conflicts with
[CRUD-Only State Persistence](https://banes-lab.com/records/lexicon/crud-only-state-persistence.md)

Referenced by
[Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md), [CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md), [Append-Only Log](https://banes-lab.com/records/architecture/append-only-log.md)

Tensions
[Event Sourcing / Query Complexity](https://banes-lab.com/records/tension/event-sourcing-query-complexity.md)

Distinct from
[CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md): Event sourcing stores state as its events, while CQRS separates the command model from the query model whatever the storage.

Distinct from
[Append-Only Log](https://banes-lab.com/records/architecture/append-only-log.md): Event sourcing rebuilds state by replay, while an append-only log is the storage it replays from.

Distinct from
[Domain Events](https://banes-lab.com/records/architecture/domain-events.md): Event sourcing makes events the source of state, while domain events can be published with state stored some other way.

Distinct from
[Saga](https://banes-lab.com/records/lexicon/saga.md): Event sourcing is how state is stored, while a saga is how a distributed transaction is coordinated.

Violated by
mutating state without event record

Detected by
state changes lacking events

Measured by
event/state consistency

Refactored by
Persist Events, Build Projections

Enforced by
event append rules

Before

```typescript
type FooRow = { id: FooId; name: string; status: string };
await fooTable.update(foo);
```

After

```typescript
type FooEvent = FooCreated | FooRenamed | FooClosed;
await fooEventStore.append(foo.id, foo.uncommittedEvents());
const foo = fooEventStore.read(fooId).reduce(applyFooEvent, emptyFoo());
```

How it is checked

Checked by
event append rules

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Append-Only Log](https://banes-lab.com/records/architecture/append-only-log.md), [Domain Events](https://banes-lab.com/records/architecture/domain-events.md), [Auditability](https://banes-lab.com/records/architecture/auditability.md), [Temporal Modeling](https://banes-lab.com/records/lexicon/temporal-modeling.md), [Replay](https://banes-lab.com/records/lexicon/replay.md), [Replay](https://banes-lab.com/records/lexicon/replay.md)

Shape it refuses
[CRUD-Only State Persistence](https://banes-lab.com/records/lexicon/crud-only-state-persistence.md)

### CQRS

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: application, data access
- Aliases: CQRS
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that separates the model that handles commands from the model that answers queries.

Requires
[Command/Query Separation](https://banes-lab.com/records/lexicon/command-query-separation.md)

Reinforces
[Scalability](https://banes-lab.com/records/architecture/scalability.md), [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md)

Enables
[Read/Write Model Optimization](https://banes-lab.com/records/lexicon/read-write-model-optimization.md)

In tension with
[Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md)

Conflicts with
[Unified CRUD Model](https://banes-lab.com/records/lexicon/unified-crud-model.md)

Referenced by
[Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

Tensions
[CQRS / Eventual Consistency](https://banes-lab.com/records/tension/cqrs-eventual-consistency.md)

Distinct from
[Saga](https://banes-lab.com/records/lexicon/saga.md): CQRS splits the write model from the read model, while a saga sequences local transactions with compensations.

Violated by
queries mutating state, commands returning complex read models

Detected by
command/query side-effect violations

Measured by
read/write separation compliance

Refactored by
Split Command and Query Models

Enforced by
handler conventions, [tests](https://banes-lab.com/records/lexicon/tests.md)

Before

```typescript
class FooRepository {
save(foo: Foo) {}
search(query: string): Foo[] { return complexJoin(query); }
}
```

After

```typescript
class FooCommandStore { save(foo: Foo) { return fooDb.write(foo); } }
class FooQueryStore { search(query: string) { return fooReadModel.search(query); } }
commandBus.execute(new SaveFoo(foo));
queryBus.execute(new SearchFoos(query));
```

How it is checked

Checked by
handler conventions, tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Command/Query Separation](https://banes-lab.com/records/lexicon/command-query-separation.md), [Scalability](https://banes-lab.com/records/architecture/scalability.md), [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md), [Read/Write Model Optimization](https://banes-lab.com/records/lexicon/read-write-model-optimization.md)

Shape it refuses
[Unified CRUD Model](https://banes-lab.com/records/lexicon/unified-crud-model.md)

### Domain Events

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [recommended](https://banes-lab.com/records/vocabulary/severity-recommended.md)
- Scope: domain, bounded context
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that records each significant change in the domain as an event named in the domain's language.

Requires
[Domain Model](https://banes-lab.com/records/architecture/domain-model.md), [Event Semantics](https://banes-lab.com/records/lexicon/event-semantics.md)

Reinforces
[Domain-Driven Design (DDD)](https://banes-lab.com/records/architecture/domain-driven-design.md), [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

Enables
[Decoupled Domain Reactions](https://banes-lab.com/records/lexicon/decoupled-domain-reactions.md)

In tension with
[Event Granularity](https://banes-lab.com/records/lexicon/event-granularity.md)

Conflicts with
[Infrastructure Events in Domain](https://banes-lab.com/records/lexicon/infrastructure-events-in-domain.md)

Referenced by
[Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md)

Tensions
[Domain Events / Event Granularity](https://banes-lab.com/records/tension/domain-events-event-granularity.md)

Violated by
events named after technical operations only

Detected by
CRUD-named domain events

Measured by
semantic event quality

Refactored by
Rename Event, Emit from Aggregate

Enforced by
domain review

Before

```typescript
class Foo {
rename(name: string) { this.name = name; }
}
```

After

```typescript
class Foo {
#events: FooDomainEvent[] = [];
rename(name: string) {
this.name = name;
this.#events.push({ type: "FooRenamed", fooId: this.id, name });
}
}
```

How it is checked

Checked by
domain review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Domain Model](https://banes-lab.com/records/architecture/domain-model.md), [Event Semantics](https://banes-lab.com/records/lexicon/event-semantics.md), [Domain-Driven Design (DDD)](https://banes-lab.com/records/architecture/domain-driven-design.md), [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md), [Decoupled Domain Reactions](https://banes-lab.com/records/lexicon/decoupled-domain-reactions.md)

Shape it refuses
[Infrastructure Events in Domain](https://banes-lab.com/records/lexicon/infrastructure-events-in-domain.md)

### Integration Events

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [recommended](https://banes-lab.com/records/vocabulary/severity-recommended.md)
- Scope: service boundary, messaging
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that publishes a versioned public event, mapped from an internal domain event, for consumers outside the service.

Requires
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Versioning](https://banes-lab.com/records/architecture/versioning.md)

Reinforces
[Interoperability](https://banes-lab.com/records/architecture/interoperability.md)

Enables
[Cross-Service Communication](https://banes-lab.com/records/lexicon/cross-service-communication.md)

In tension with
[Duplication with Domain Events](https://banes-lab.com/records/lexicon/duplication-with-domain-events.md)

Conflicts with
[Internal Domain Event Leakage](https://banes-lab.com/records/lexicon/internal-domain-event-leakage.md)

Tensions
[Integration Events / Duplication with Domain Events](https://banes-lab.com/records/tension/duplication-with-domain-events-integration-events.md)

Violated by
exposing internal domain events directly to external consumers

Detected by
internal event schema published externally

Measured by
boundary event contract coverage

Refactored by
Map Domain Event to Integration Event

Enforced by
event schema review

Before

```typescript
barService.consume(fooDomainEvent);
```

After

```typescript
const integrationEvent: FooCreatedV1 = {
type: "com.example.foo-created.v1",
fooId: event.fooId,
occurredAt: clock.now().toISOString(),
};
integrationBus.publish(integrationEvent);
```

How it is checked

Checked by
event schema review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Versioning](https://banes-lab.com/records/architecture/versioning.md), [Interoperability](https://banes-lab.com/records/architecture/interoperability.md), [Cross-Service Communication](https://banes-lab.com/records/lexicon/cross-service-communication.md)

Shape it refuses
[Internal Domain Event Leakage](https://banes-lab.com/records/lexicon/internal-domain-event-leakage.md)

### Asynchronous Communication

- Kind: [principle](https://banes-lab.com/records/kind/principle.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: service, system
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design rule that work the caller does not need at once is sent as a message, so the caller does not wait on it.

Requires
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Retry Safety](https://banes-lab.com/records/lexicon/retry-safety.md)

Reinforces
[Resilience](https://banes-lab.com/records/architecture/resilience.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)

Enables
[Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

In tension with
[Immediate Consistency](https://banes-lab.com/records/lexicon/immediate-consistency.md)

Conflicts with
[Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md)

Referenced by
[Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

Tensions
[Asynchronous Communication / Immediate Consistency](https://banes-lab.com/records/tension/asynchronous-communication-immediate-consistency.md)

Violated by
synchronous call chain for non-immediate work

Detected by
long blocking chains

Measured by
sync dependency depth

Refactored by
Introduce Queue/Event, Add Callback/Projection

Enforced by
[architecture review](https://banes-lab.com/records/architecture/architecture-review.md)

Before

```typescript
const bar = await barService.createFromFoo(foo);
const baz = await bazService.createFromBar(bar);
```

After

```typescript
await outbox.append({ type: "FooCreated", fooId: foo.id });
return { accepted: true, fooId: foo.id };
```

How it is checked

Checked by
architecture review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Contract](https://banes-lab.com/records/lexicon/message-contract.md), [Retry Safety](https://banes-lab.com/records/lexicon/retry-safety.md), [Resilience](https://banes-lab.com/records/architecture/resilience.md), [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md), [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)

Shape it refuses
[Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md), [Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md)

### Eventual Consistency

- Kind: [model](https://banes-lab.com/records/kind/model.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: distributed system, data
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A conceptual representation of a consistency guarantee in which replicas and projections converge once updates stop arriving.

Requires
[Idempotency](https://banes-lab.com/records/architecture/idempotency.md), [Retry](https://banes-lab.com/records/lexicon/retry.md), [Reconciliation](https://banes-lab.com/records/lexicon/reconciliation.md)

Reinforces
[Availability](https://banes-lab.com/records/lexicon/availability.md), [Scalability](https://banes-lab.com/records/architecture/scalability.md)

Enables
[Distributed Autonomy](https://banes-lab.com/records/lexicon/distributed-autonomy.md)

In tension with
[User Expectations](https://banes-lab.com/records/lexicon/user-expectations.md), [Strong Immediate Consistency](https://banes-lab.com/records/lexicon/strong-immediate-consistency.md)

Conflicts with
none

Referenced by
[CRDTs](https://banes-lab.com/records/architecture/crdts.md), [CAP Theorem](https://banes-lab.com/records/architecture/cap-theorem.md), [CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md), [Saga Pattern](https://banes-lab.com/records/architecture/saga-pattern.md), [Idempotent Consumer](https://banes-lab.com/records/architecture/idempotent-consumer.md)

Tensions
[Eventual Consistency / User Expectations](https://banes-lab.com/records/tension/eventual-consistency-user-expectations.md), [Eventual Consistency / Strong Immediate Consistency](https://banes-lab.com/records/tension/eventual-consistency-strong-immediate-consistency.md)

Distinct from
[Causal Consistency](https://banes-lab.com/records/architecture/causal-consistency.md): Eventual consistency promises only that replicas converge, while causal consistency also promises that no effect is read before its cause.

Violated by
assuming immediate cross-service consistency

Detected by
synchronous compensation hacks

Measured by
convergence time, inconsistency window

Refactored by
Add Projection, Add Reconciliation, Add Saga

Enforced by
consistency tests

Before

```typescript
await fooStore.save(foo);
await fooSearch.update(foo);
await fooAnalytics.update(foo);
```

After

```typescript
await fooStore.save(foo);
fooEvents.emit({ type: "FooSaved", foo });
const view = await fooSearchView.find(foo.id);
const converged = view.version >= foo.version;
return { foo: view, converged };
```

How it is checked

Checked by
consistency tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Idempotency](https://banes-lab.com/records/architecture/idempotency.md), [Retry](https://banes-lab.com/records/lexicon/retry.md), [Reconciliation](https://banes-lab.com/records/lexicon/reconciliation.md), [Availability](https://banes-lab.com/records/lexicon/availability.md), [Scalability](https://banes-lab.com/records/architecture/scalability.md), [Distributed Autonomy](https://banes-lab.com/records/lexicon/distributed-autonomy.md)

Shape it refuses
Not answered

### Saga Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: service workflow, distributed system
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that runs a cross-service transaction as a sequence of local steps, each paired with a compensating step.

Requires
[Compensating Transactions](https://banes-lab.com/records/lexicon/compensating-transactions.md), [Idempotency](https://banes-lab.com/records/architecture/idempotency.md)

Reinforces
[Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md)

Enables
[Long-Running Transactions](https://banes-lab.com/records/lexicon/long-running-transactions.md)

In tension with
[Workflow Complexity](https://banes-lab.com/records/lexicon/workflow-complexity.md)

Conflicts with
[Global ACID Transaction](https://banes-lab.com/records/lexicon/global-acid-transaction.md)

Referenced by
[Compensating Transaction](https://banes-lab.com/records/architecture/compensating-transaction.md)

Tensions
[Saga Pattern / Workflow Complexity](https://banes-lab.com/records/tension/saga-pattern-workflow-complexity.md)

Violated by
cross-service transaction requiring atomic database commit

Detected by
distributed transaction attempts

Measured by
compensation coverage

Refactored by
Introduce Saga, Add Compensation

Enforced by
workflow tests

Before

```typescript
const tx = coordinator.begin();
await fooService.prepare(tx, foo);
await barService.prepare(tx, bar);
await bazService.prepare(tx, baz);
await coordinator.commit(tx);
```

After

```typescript
await saga([
{ action: () => fooService.create(foo), compensate: id => fooService.cancel(id) },
{ action: () => barService.create(bar), compensate: id => barService.cancel(id) },
{ action: () => bazService.create(baz), compensate: id => bazService.cancel(id) },
]).run();
```

How it is checked

Checked by
workflow tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Compensating Transactions](https://banes-lab.com/records/lexicon/compensating-transactions.md), [Idempotency](https://banes-lab.com/records/architecture/idempotency.md), [Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md), [Long-Running Transactions](https://banes-lab.com/records/lexicon/long-running-transactions.md)

Shape it refuses
[Global ACID Transaction](https://banes-lab.com/records/lexicon/global-acid-transaction.md)

### Outbox Pattern

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [recommended](https://banes-lab.com/records/vocabulary/severity-recommended.md)
- Scope: persistence, messaging
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that writes an outgoing message in the same local transaction as the state change, and a relay publishes it afterwards.

Requires
[Local Transaction](https://banes-lab.com/records/lexicon/local-transaction.md), [Message Relay](https://banes-lab.com/records/lexicon/message-relay.md)

Reinforces
[Event Reliability](https://banes-lab.com/records/lexicon/event-reliability.md)

Enables
[Atomic State Change + Message Publish](https://banes-lab.com/records/lexicon/atomic-state-change-message-publish.md)

In tension with
[Relay Complexity](https://banes-lab.com/records/lexicon/relay-complexity.md)

Conflicts with
[Dual Write](https://banes-lab.com/records/architecture/dual-write.md)

Tensions
[Outbox Pattern / Relay Complexity](https://banes-lab.com/records/tension/outbox-pattern-relay-complexity.md)

Violated by
database write followed by direct publish without atomicity

Detected by
dual-write patterns

Measured by
lost-message rate, outbox coverage

Refactored by
Add Outbox Table, Add Relay Worker

Enforced by
persistence rules, integration tests

Before

```typescript
await fooStore.save(foo);
await eventBus.publish({ type: "FooSaved", fooId: foo.id });
```

After

```typescript
await database.transaction(async tx => {
await tx.foos.save(foo);
await tx.outbox.insert({ id: eventId(), type: "FooSaved", fooId: foo.id });
});
await outboxRelay.publishPending();
```

How it is checked

Checked by
persistence rules, integration tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Local Transaction](https://banes-lab.com/records/lexicon/local-transaction.md), [Message Relay](https://banes-lab.com/records/lexicon/message-relay.md), [Event Reliability](https://banes-lab.com/records/lexicon/event-reliability.md), [Atomic State Change + Message Publish](https://banes-lab.com/records/lexicon/atomic-state-change-message-publish.md)

Shape it refuses
[Dual Write](https://banes-lab.com/records/architecture/dual-write.md)

### Compensating Transaction

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: workflow, distributed transaction
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A mechanism that undoes the business effect of a completed step when a later step of the workflow fails.

Requires
[Reversible/Compensable Step](https://banes-lab.com/records/lexicon/reversible-compensable-step.md)

Reinforces
[Saga Pattern](https://banes-lab.com/records/architecture/saga-pattern.md), [Resilience](https://banes-lab.com/records/architecture/resilience.md)

Enables
[Failure Recovery](https://banes-lab.com/records/lexicon/failure-recovery.md)

In tension with
[Business Complexity](https://banes-lab.com/records/lexicon/business-complexity.md)

Conflicts with
[Irreversible Side Effects](https://banes-lab.com/records/lexicon/irreversible-side-effects.md)

Tensions
[Compensating Transaction / Business Complexity](https://banes-lab.com/records/tension/business-complexity-compensating-transaction.md)

Violated by
unrecoverable partial workflow failure

Detected by
saga steps without compensation

Measured by
compensation coverage

Refactored by
Add Compensation Action

Enforced by
workflow tests

Before

```typescript
await fooService.create(foo);
await barService.create(bar);
```

After

```typescript
const fooId = await fooService.create(foo);
try {
await barService.create(bar);
} catch (error) {
await fooService.compensateCreate(fooId);
throw error;
}
```

How it is checked

Checked by
workflow tests

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Reversible/Compensable Step](https://banes-lab.com/records/lexicon/reversible-compensable-step.md), [Saga Pattern](https://banes-lab.com/records/architecture/saga-pattern.md), [Resilience](https://banes-lab.com/records/architecture/resilience.md), [Failure Recovery](https://banes-lab.com/records/lexicon/failure-recovery.md)

Shape it refuses
[Irreversible Side Effects](https://banes-lab.com/records/lexicon/irreversible-side-effects.md)

### Append-Only Log

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: event store, audit, stream
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that records history as immutable entries added at the end of the log.

Requires
[Immutable Events](https://banes-lab.com/records/lexicon/immutable-events.md)

Reinforces
[Auditability](https://banes-lab.com/records/architecture/auditability.md), [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md)

Enables
[Replay](https://banes-lab.com/records/lexicon/replay.md), [Temporal Queries](https://banes-lab.com/records/lexicon/temporal-queries.md)

In tension with
[Storage Growth](https://banes-lab.com/records/lexicon/storage-growth.md)

Conflicts with
[In-Place Mutation](https://banes-lab.com/records/lexicon/in-place-mutation.md)

Referenced by
[Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md)

Tensions
[Append-Only Log / Storage Growth](https://banes-lab.com/records/tension/append-only-log-storage-growth.md)

Distinct from
[Domain Events](https://banes-lab.com/records/architecture/domain-events.md): An append-only log is the storage shape that never rewrites an entry, while domain events are what gets recorded, named in the domain's language.

Violated by
updating historical records destructively

Detected by
mutable event rows

Measured by
append-only compliance

Refactored by
Append Events, Add Snapshot/Compaction

Enforced by
database constraints

Before

```typescript
fooState.set(foo.id, foo);
fooState.delete(foo.id);
```

After

```typescript
type FooLogEntry = FooCreated | FooUpdated | FooRemoved;
fooLog.append({ seq: nextSeq(), type: "FooRemoved", fooId: foo.id });
const state = projectFooLog(fooLog.read());
```

How it is checked

Checked by
database constraints

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Immutable Events](https://banes-lab.com/records/lexicon/immutable-events.md), [Auditability](https://banes-lab.com/records/architecture/auditability.md), [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md), [Replay](https://banes-lab.com/records/lexicon/replay.md), [Temporal Queries](https://banes-lab.com/records/lexicon/temporal-queries.md)

Shape it refuses
[In-Place Mutation](https://banes-lab.com/records/lexicon/in-place-mutation.md)

### Dead-Letter Queue

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Mandatory for: production systems
- Scope: service, messaging, resilience
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern that moves a message which keeps failing into a separate queue, where it can be inspected and reprocessed.

Requires
[Message Queue](https://banes-lab.com/records/architecture/message-queue.md)

Reinforces
[Fault Isolation](https://banes-lab.com/records/lexicon/fault-isolation.md), [Observability](https://banes-lab.com/records/architecture/observability.md)

Enables
[Poison-Message Quarantine](https://banes-lab.com/records/lexicon/poison-message-quarantine.md), [Reprocessing After Fix](https://banes-lab.com/records/lexicon/reprocessing-after-fix.md)

In tension with
[Operational Overhead](https://banes-lab.com/records/lexicon/operational-overhead.md)

Conflicts with
[Infinite Redelivery Loop](https://banes-lab.com/records/lexicon/infinite-redelivery-loop.md)

Tensions
[Dead-Letter Queue / Operational Overhead](https://banes-lab.com/records/tension/dead-letter-queue-operational-overhead.md)

Violated by
unprocessable messages redelivered forever

Detected by
retry storms on a single poison message

Measured by
redelivery count per failed message

Refactored by
Route Failures to a Dead-Letter Queue

Enforced by
messaging design review

Before

```typescript
worker.consume(fooQueue, async message => {
await processFoo(message);
});
```

After

```typescript
worker.consume(fooQueue, async message => {
try {
await processFoo(message);
} catch (error) {
if (message.attempts >= 5) return fooDeadLetterQueue.send(message, error);
throw error;
}
});
```

How it is checked

Checked by
messaging design review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Queue](https://banes-lab.com/records/architecture/message-queue.md), [Fault Isolation](https://banes-lab.com/records/lexicon/fault-isolation.md), [Observability](https://banes-lab.com/records/architecture/observability.md), [Poison-Message Quarantine](https://banes-lab.com/records/lexicon/poison-message-quarantine.md), [Reprocessing After Fix](https://banes-lab.com/records/lexicon/reprocessing-after-fix.md)

Shape it refuses
[Infinite Redelivery Loop](https://banes-lab.com/records/lexicon/infinite-redelivery-loop.md)

### Idempotent Consumer

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Mandatory for: distributed systems
- Scope: service, messaging, correctness
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern in which a consumer records each message it has processed, so a redelivered message has no second effect.

Requires
[Deduplication Key](https://banes-lab.com/records/lexicon/deduplication-key.md)

Reinforces
[Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md), [At-Least-Once Delivery Safety](https://banes-lab.com/records/lexicon/at-least-once-delivery-safety.md)

Enables
[Safe Message Redelivery](https://banes-lab.com/records/lexicon/safe-message-redelivery.md)

In tension with
[State Overhead](https://banes-lab.com/records/lexicon/state-overhead.md)

Conflicts with
[Duplicate Side Effects](https://banes-lab.com/records/lexicon/duplicate-side-effects.md)

Tensions
[Idempotent Consumer / State Overhead](https://banes-lab.com/records/tension/idempotent-consumer-state-overhead.md)

Violated by
a redelivered message applied twice

Detected by
duplicate effects under at-least-once delivery

Measured by
duplicate-processing incident rate

Refactored by
Make the Consumer Idempotent

Enforced by
messaging design review

Before

```typescript
worker.consume(fooQueue, message => chargeFoo(message.fooId, message.amount));
```

After

```typescript
worker.consume(fooQueue, async message => {
if (await processedMessages.has(message.id)) return;
await chargeFoo(message.fooId, message.amount);
await processedMessages.add(message.id);
});
```

How it is checked

Checked by
messaging design review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Deduplication Key](https://banes-lab.com/records/lexicon/deduplication-key.md), [Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md), [At-Least-Once Delivery Safety](https://banes-lab.com/records/lexicon/at-least-once-delivery-safety.md), [Safe Message Redelivery](https://banes-lab.com/records/lexicon/safe-message-redelivery.md)

Shape it refuses
[Duplicate Side Effects](https://banes-lab.com/records/lexicon/duplicate-side-effects.md)

### Competing Consumers

- Kind: [pattern](https://banes-lab.com/records/kind/pattern.md)
- Category: [Event / Messaging / Asynchronous Architecture](https://banes-lab.com/ontology/principles/architecture-category-event-messaging-asynchronous-architecture.md)
- Severity: [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- Scope: service, messaging, scalability
- Layer: [Execution Core](https://banes-lab.com/records/layer/execution-core.md)

Details

Definition
A design pattern in which several consumers read from one queue, and each message goes to only one of them.

Requires
[Message Queue](https://banes-lab.com/records/architecture/message-queue.md)

Reinforces
[Horizontal Scaling](https://banes-lab.com/records/architecture/horizontal-scaling.md), [Load Balancing](https://banes-lab.com/records/architecture/load-balancing.md)

Enables
[Parallel Message Processing](https://banes-lab.com/records/lexicon/parallel-message-processing.md), [Consumer Elasticity](https://banes-lab.com/records/lexicon/consumer-elasticity.md)

In tension with
[Ordering](https://banes-lab.com/records/lexicon/ordering.md)

Conflicts with
[Single Serial Consumer](https://banes-lab.com/records/lexicon/single-serial-consumer.md)

Tensions
[Competing Consumers / Ordering](https://banes-lab.com/records/tension/competing-consumers-ordering.md)

Violated by
one consumer serially draining a growing backlog

Detected by
queue depth rising with a single processor

Measured by
consumer utilization vs backlog growth

Refactored by
Scale Out Competing Consumers

Enforced by
messaging design review

Before

```typescript
fooWorker.consume(fooQueue, processFoo);
```

After

```typescript
for (let worker = 0; worker < WORKER_COUNT; worker += 1) {
new FooWorker(worker).consume(fooQueue, processFoo);
}
```

How it is checked

Checked by
messaging design review

Population
Every event, message, topic and consumer that crosses an asynchronous boundary

Freshness
A verdict stands until an event schema, a consumer or the delivery guarantee changes

Refusal
The schema registry, idempotency test or workflow test fails the change that breaks delivery or contract

Observation
Published schemas, consumer registrations, and redelivery, lag and dead-letter counts from the broker

Evidence
None, because the catalog states this check as a class, so a watched run belongs to each system that adopts it

Authoritative side
The published schema and the delivery guarantee, which every producer and consumer conforms to

Depends on
[Message Queue](https://banes-lab.com/records/architecture/message-queue.md), [Horizontal Scaling](https://banes-lab.com/records/architecture/horizontal-scaling.md), [Load Balancing](https://banes-lab.com/records/architecture/load-balancing.md), [Parallel Message Processing](https://banes-lab.com/records/lexicon/parallel-message-processing.md), [Consumer Elasticity](https://banes-lab.com/records/lexicon/consumer-elasticity.md)

Shape it refuses
[Single Serial Consumer](https://banes-lab.com/records/lexicon/single-serial-consumer.md)

## Links to

- [style](https://banes-lab.com/records/kind/style.md)
- [contextual](https://banes-lab.com/records/vocabulary/severity-contextual.md)
- [Execution Core](https://banes-lab.com/records/layer/execution-core.md)
- [Events](https://banes-lab.com/records/lexicon/events.md)
- [Message Contract](https://banes-lab.com/records/lexicon/message-contract.md)
- [Idempotency](https://banes-lab.com/records/architecture/idempotency.md)
- [Low Coupling](https://banes-lab.com/records/architecture/low-coupling.md)
- [Asynchronous Communication](https://banes-lab.com/records/architecture/asynchronous-communication.md)
- [Event Sourcing](https://banes-lab.com/records/architecture/event-sourcing.md)
- [CQRS](https://banes-lab.com/records/architecture/command-query-responsibility-segregation.md)
- [Saga](https://banes-lab.com/records/lexicon/saga.md)
- [Debuggability](https://banes-lab.com/records/lexicon/debuggability.md)
- [Strong Consistency](https://banes-lab.com/records/lexicon/strong-consistency.md)
- [Hidden Temporal Coupling](https://banes-lab.com/records/lexicon/hidden-temporal-coupling.md)
- [Choreography](https://banes-lab.com/records/architecture/choreography.md)
- [Event Bus](https://banes-lab.com/records/architecture/event-bus.md)
- [Domain Events](https://banes-lab.com/records/architecture/domain-events.md)
- [Observer Pattern](https://banes-lab.com/records/architecture/observer-pattern.md)
- [Event-Driven Architecture / Debuggability](https://banes-lab.com/records/tension/debuggability-event-driven-architecture.md)
- [Event-Driven Architecture / Strong Consistency](https://banes-lab.com/records/tension/event-driven-architecture-strong-consistency.md)
- [Retry Safety](https://banes-lab.com/records/lexicon/retry-safety.md)
- [pattern](https://banes-lab.com/records/kind/pattern.md)
- [Publisher](https://banes-lab.com/records/lexicon/publisher.md)
- [Subscriber](https://banes-lab.com/records/lexicon/subscriber.md)
- [Broker/Event Bus](https://banes-lab.com/records/lexicon/broker-event-bus.md)
- [Fan-Out Notification](https://banes-lab.com/records/lexicon/fan-out-notification.md)
- [Delivery Ordering](https://banes-lab.com/records/lexicon/delivery-ordering.md)
- [Direct Point-to-Point Calls](https://banes-lab.com/records/lexicon/direct-point-to-point-calls.md)
- [Publish/Subscribe Pattern / Delivery Ordering](https://banes-lab.com/records/tension/delivery-ordering-publish-subscribe-pattern.md)
- [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- [Consumer](https://banes-lab.com/records/lexicon/consumer.md)
- [Resilience](https://banes-lab.com/records/architecture/resilience.md)
- [Backpressure](https://banes-lab.com/records/architecture/backpressure.md)
- [Asynchronous Processing](https://banes-lab.com/records/lexicon/asynchronous-processing.md)
- [Latency](https://banes-lab.com/records/architecture/latency.md)
- [In-Memory Direct Invocation](https://banes-lab.com/records/lexicon/in-memory-direct-invocation.md)
- [Dead-Letter Queue](https://banes-lab.com/records/architecture/dead-letter-queue.md)
- [Competing Consumers](https://banes-lab.com/records/architecture/competing-consumers.md)
- [Message Queue / Latency](https://banes-lab.com/records/tension/latency-message-queue.md)
- [artifact](https://banes-lab.com/records/kind/artifact.md)
- [Message Queue/Topics](https://banes-lab.com/records/lexicon/message-queue-topics.md)
- [Routing](https://banes-lab.com/records/lexicon/routing.md)
- [Scalability](https://banes-lab.com/records/architecture/scalability.md)
- [Pub/Sub](https://banes-lab.com/records/lexicon/pub-sub.md)
- [Work Distribution](https://banes-lab.com/records/lexicon/work-distribution.md)
- [Operational Dependency](https://banes-lab.com/records/lexicon/operational-dependency.md)
- [Point-to-Point Coupling](https://banes-lab.com/records/lexicon/point-to-point-coupling.md)
- [Message Broker / Operational Dependency](https://banes-lab.com/records/tension/message-broker-operational-dependency.md)
- [Event Contract](https://banes-lab.com/records/lexicon/event-contract.md)
- [Subscriber Model](https://banes-lab.com/records/lexicon/subscriber-model.md)
- [Event-Driven Architecture](https://banes-lab.com/records/architecture/event-driven-architecture.md)
- [Decoupled Event Distribution](https://banes-lab.com/records/lexicon/decoupled-event-distribution.md)
- [Event Storm / Traceability](https://banes-lab.com/records/lexicon/event-storm-traceability.md)
- [Direct Event Handler Calls](https://banes-lab.com/records/lexicon/direct-event-handler-calls.md)
- [Event Bus / Event Storm / Traceability](https://banes-lab.com/records/tension/event-bus-event-storm-traceability.md)
- [Ordered Log](https://banes-lab.com/records/lexicon/ordered-log.md)
- [Event Schema](https://banes-lab.com/records/lexicon/event-schema.md)
- [Streaming Architecture](https://banes-lab.com/records/architecture/streaming-architecture.md)
- [Replay](https://banes-lab.com/records/lexicon/replay.md)
- [Continuous Processing](https://banes-lab.com/records/lexicon/continuous-processing.md)
- [Storage Volume](https://banes-lab.com/records/lexicon/storage-volume.md)
- [Mutable State Only](https://banes-lab.com/records/lexicon/mutable-state-only.md)
- [Event Stream / Storage Volume](https://banes-lab.com/records/tension/event-stream-storage-volume.md)
- [Append-Only Log](https://banes-lab.com/records/architecture/append-only-log.md)
- [Auditability](https://banes-lab.com/records/architecture/auditability.md)
- [Temporal Modeling](https://banes-lab.com/records/lexicon/temporal-modeling.md)
- [Query Complexity](https://banes-lab.com/records/lexicon/query-complexity.md)
- [CRUD-Only State Persistence](https://banes-lab.com/records/lexicon/crud-only-state-persistence.md)
- [Event Sourcing / Query Complexity](https://banes-lab.com/records/tension/event-sourcing-query-complexity.md)
- [Command/Query Separation](https://banes-lab.com/records/lexicon/command-query-separation.md)
- [Read/Write Model Optimization](https://banes-lab.com/records/lexicon/read-write-model-optimization.md)
- [Eventual Consistency](https://banes-lab.com/records/architecture/eventual-consistency.md)
- [Unified CRUD Model](https://banes-lab.com/records/lexicon/unified-crud-model.md)
- [CQRS / Eventual Consistency](https://banes-lab.com/records/tension/cqrs-eventual-consistency.md)
- [Tests](https://banes-lab.com/records/lexicon/tests.md)
- [recommended](https://banes-lab.com/records/vocabulary/severity-recommended.md)
- [Domain Model](https://banes-lab.com/records/architecture/domain-model.md)
- [Event Semantics](https://banes-lab.com/records/lexicon/event-semantics.md)
- [Domain-Driven Design](https://banes-lab.com/records/architecture/domain-driven-design.md)
- [Decoupled Domain Reactions](https://banes-lab.com/records/lexicon/decoupled-domain-reactions.md)
- [Event Granularity](https://banes-lab.com/records/lexicon/event-granularity.md)
- [Infrastructure Events in Domain](https://banes-lab.com/records/lexicon/infrastructure-events-in-domain.md)
- [Domain Events / Event Granularity](https://banes-lab.com/records/tension/domain-events-event-granularity.md)
- [Versioning](https://banes-lab.com/records/architecture/versioning.md)
- [Interoperability](https://banes-lab.com/records/architecture/interoperability.md)
- [Cross-Service Communication](https://banes-lab.com/records/lexicon/cross-service-communication.md)
- [Duplication with Domain Events](https://banes-lab.com/records/lexicon/duplication-with-domain-events.md)
- [Internal Domain Event Leakage](https://banes-lab.com/records/lexicon/internal-domain-event-leakage.md)
- [Integration Events / Duplication with Domain Events](https://banes-lab.com/records/tension/duplication-with-domain-events-integration-events.md)
- [principle](https://banes-lab.com/records/kind/principle.md)
- [Immediate Consistency](https://banes-lab.com/records/lexicon/immediate-consistency.md)
- [Synchronous Chain Trap](https://banes-lab.com/records/architecture/synchronous-chain-trap.md)
- [Asynchronous Communication / Immediate Consistency](https://banes-lab.com/records/tension/asynchronous-communication-immediate-consistency.md)
- [Architecture Review](https://banes-lab.com/records/architecture/architecture-review.md)
- [model](https://banes-lab.com/records/kind/model.md)
- [Retry](https://banes-lab.com/records/lexicon/retry.md)
- [Reconciliation](https://banes-lab.com/records/lexicon/reconciliation.md)
- [Availability](https://banes-lab.com/records/lexicon/availability.md)
- [Distributed Autonomy](https://banes-lab.com/records/lexicon/distributed-autonomy.md)
- [User Expectations](https://banes-lab.com/records/lexicon/user-expectations.md)
- [Strong Immediate Consistency](https://banes-lab.com/records/lexicon/strong-immediate-consistency.md)
- [CRDTs](https://banes-lab.com/records/architecture/crdts.md)
- [CAP Theorem](https://banes-lab.com/records/architecture/cap-theorem.md)
- [Saga Pattern](https://banes-lab.com/records/architecture/saga-pattern.md)
- [Idempotent Consumer](https://banes-lab.com/records/architecture/idempotent-consumer.md)
- [Eventual Consistency / User Expectations](https://banes-lab.com/records/tension/eventual-consistency-user-expectations.md)
- [Eventual Consistency / Strong Immediate Consistency](https://banes-lab.com/records/tension/eventual-consistency-strong-immediate-consistency.md)
- [Causal Consistency](https://banes-lab.com/records/architecture/causal-consistency.md)
- [Compensating Transactions](https://banes-lab.com/records/lexicon/compensating-transactions.md)
- [Long-Running Transactions](https://banes-lab.com/records/lexicon/long-running-transactions.md)
- [Workflow Complexity](https://banes-lab.com/records/lexicon/workflow-complexity.md)
- [Global ACID Transaction](https://banes-lab.com/records/lexicon/global-acid-transaction.md)
- [Compensating Transaction](https://banes-lab.com/records/architecture/compensating-transaction.md)
- [Saga Pattern / Workflow Complexity](https://banes-lab.com/records/tension/saga-pattern-workflow-complexity.md)
- [Local Transaction](https://banes-lab.com/records/lexicon/local-transaction.md)
- [Message Relay](https://banes-lab.com/records/lexicon/message-relay.md)
- [Event Reliability](https://banes-lab.com/records/lexicon/event-reliability.md)
- [Atomic State Change + Message Publish](https://banes-lab.com/records/lexicon/atomic-state-change-message-publish.md)
- [Relay Complexity](https://banes-lab.com/records/lexicon/relay-complexity.md)
- [Dual Write](https://banes-lab.com/records/architecture/dual-write.md)
- [Outbox Pattern / Relay Complexity](https://banes-lab.com/records/tension/outbox-pattern-relay-complexity.md)
- [Reversible/Compensable Step](https://banes-lab.com/records/lexicon/reversible-compensable-step.md)
- [Failure Recovery](https://banes-lab.com/records/lexicon/failure-recovery.md)
- [Business Complexity](https://banes-lab.com/records/lexicon/business-complexity.md)
- [Irreversible Side Effects](https://banes-lab.com/records/lexicon/irreversible-side-effects.md)
- [Compensating Transaction / Business Complexity](https://banes-lab.com/records/tension/business-complexity-compensating-transaction.md)
- [Immutable Events](https://banes-lab.com/records/lexicon/immutable-events.md)
- [Temporal Queries](https://banes-lab.com/records/lexicon/temporal-queries.md)
- [Storage Growth](https://banes-lab.com/records/lexicon/storage-growth.md)
- [In-Place Mutation](https://banes-lab.com/records/lexicon/in-place-mutation.md)
- [Append-Only Log / Storage Growth](https://banes-lab.com/records/tension/append-only-log-storage-growth.md)
- [Message Queue](https://banes-lab.com/records/architecture/message-queue.md)
- [Fault Isolation](https://banes-lab.com/records/lexicon/fault-isolation.md)
- [Observability](https://banes-lab.com/records/architecture/observability.md)
- [Poison-Message Quarantine](https://banes-lab.com/records/lexicon/poison-message-quarantine.md)
- [Reprocessing After Fix](https://banes-lab.com/records/lexicon/reprocessing-after-fix.md)
- [Operational Overhead](https://banes-lab.com/records/lexicon/operational-overhead.md)
- [Infinite Redelivery Loop](https://banes-lab.com/records/lexicon/infinite-redelivery-loop.md)
- [Dead-Letter Queue / Operational Overhead](https://banes-lab.com/records/tension/dead-letter-queue-operational-overhead.md)
- [Deduplication Key](https://banes-lab.com/records/lexicon/deduplication-key.md)
- [At-Least-Once Delivery Safety](https://banes-lab.com/records/lexicon/at-least-once-delivery-safety.md)
- [Safe Message Redelivery](https://banes-lab.com/records/lexicon/safe-message-redelivery.md)
- [State Overhead](https://banes-lab.com/records/lexicon/state-overhead.md)
- [Duplicate Side Effects](https://banes-lab.com/records/lexicon/duplicate-side-effects.md)
- [Idempotent Consumer / State Overhead](https://banes-lab.com/records/tension/idempotent-consumer-state-overhead.md)
- [Horizontal Scaling](https://banes-lab.com/records/architecture/horizontal-scaling.md)
- [Load Balancing](https://banes-lab.com/records/architecture/load-balancing.md)
- [Parallel Message Processing](https://banes-lab.com/records/lexicon/parallel-message-processing.md)
- [Consumer Elasticity](https://banes-lab.com/records/lexicon/consumer-elasticity.md)
- [Ordering](https://banes-lab.com/records/lexicon/ordering.md)
- [Single Serial Consumer](https://banes-lab.com/records/lexicon/single-serial-consumer.md)
- [Competing Consumers / Ordering](https://banes-lab.com/records/tension/competing-consumers-ordering.md)

## Linked from

- [The layer topology](https://banes-lab.com/ontology/schema/the-layer-topology.md)
- [The membership](https://banes-lab.com/ontology/schema/the-membership.md)
