5 exercises — Practice EDA vocabulary in English: event vs command, publisher/subscriber, broker, topic, delivery guarantees (at-least-once, exactly-once), dead letter queue, and schema registry.
Core EDA vocabulary clusters
Message types: event (fact that happened), command (instruction to do something), query (request for data)
Delivery guarantees: at-most-once (may lose), at-least-once (may duplicate), exactly-once (no loss, no duplicate)
Error handling: dead letter queue (DLQ), retry policy, poison pill, schema registry (Avro, Protobuf, JSON Schema)
0 / 5 completed
1 / 5
A solutions architect explains a design decision to the team: "We're migrating from a synchronous REST-based architecture to event-driven. The core idea: services communicate through events rather than direct API calls. When an order is placed, the OrderService emits an 'OrderPlaced' event to Kafka. The InventoryService, NotificationService, and AnalyticsService all consume that event independently. OrderService doesn't know or care who consumes it — it just emits the fact. This is the difference between an event and a command. An event says 'this happened'. A command says 'please do this'. Events are for decoupling; commands are for orchestration." What is the key conceptual difference between an event and a command in messaging?
Event: a record of something that occurred — past tense, immutable. "OrderPlaced", "UserRegistered", "PaymentFailed". The emitter broadcasts to all interested parties without knowing who they are. Multiple consumers can react independently. Command: an instruction targeting a specific service — "ProcessPayment", "SendEmail", "UpdateInventory". Implies one designated handler. Typically expects acknowledgment. Query: request for data — "GetOrderById". Expects a response. EDA coupling benefits: Temporal decoupling: producer and consumer don't need to be running simultaneously (broker buffers). Interface decoupling: producer doesn't import or depend on consumer code. Deployment decoupling: services can be deployed independently. Scaling decoupling: consumers scale independently based on their own throughput needs. Naming conventions: events use past tense noun-verb: OrderPlaced, ShipmentDispatched, PaymentDeclined. Commands use imperative: PlaceOrder, ShipOrder, DeclinePayment. Message envelope vocabulary: Topic/Queue: the address to which messages are sent. Partition key: ensures messages for the same entity go to the same partition (ordering). Message ID: unique identifier for deduplication. Correlation ID: links related messages in a workflow. Timestamp: when the event occurred (not when it was published). In conversation: 'When OrderService calls InventoryService directly, it has a compile-time dependency on it. With events, those services have never heard of each other. That's the decoupling we're after.'
2 / 5
A backend engineer explains a reliability problem in the event pipeline: "Our notification service consumed Kafka events and sent emails. Sometimes the email service was temporarily down. The consumer retried three times, all failed, and the event was dropped — the user never got their email. We needed at-least-once delivery with a dead letter queue for events that exhaust all retries. Now failed events go to a DLQ topic. We have a separate process that monitors the DLQ, alerts on-call, and allows manual reprocessing after the downstream issue is resolved." What is a dead letter queue (DLQ) and when does a message end up there?
Dead letter queue (DLQ): a special destination for messages that cannot be successfully processed. Prevents one bad message from blocking an entire queue indefinitely. Causes of DLQ routing: Max retries exceeded: consumer failed N times (configurable). Poison pill: a malformed message that always causes a processing exception (e.g., invalid JSON, missing required field). Message TTL exceeded: message sat in the queue longer than its time-to-live. Consumer rejection: consumer explicitly nack'd the message without requeue. Delivery guarantee vocabulary: At-most-once: messages may be lost but never duplicated. Consumer acknowledges before processing. Simplest to implement, lowest overhead. Use for non-critical metrics. At-least-once: messages will be delivered, potentially multiple times. Consumer acknowledges after successful processing. Producer retries if no ack received. Consumers must be idempotent (safe to process duplicate messages). Exactly-once: each message delivered and processed exactly once. Requires coordination (Kafka transactions, idempotent consumers with deduplication). Highest cost/complexity. Idempotency strategies: Natural idempotency: processing the same "set name=John" twice has the same outcome. Idempotency key: consumer tracks processed message IDs and skips duplicates. Conditional updates: update only if version/timestamp matches. In conversation: 'Monitor your DLQ. A spike in DLQ messages is often your first indicator of a downstream service degradation or a schema mismatch after a deployment.'
3 / 5
A data engineer explains a breaking change incident: "Team A added a new required field to the OrderPlaced event. They forgot that Team B's analytics consumer also reads that topic. Team B's consumer didn't know about the new field and started throwing deserialization errors on every message. Their consumer stopped processing. We lost 4 hours of analytics data. This is a schema evolution failure — we needed a schema registry. With Confluent Schema Registry and Avro, producers and consumers register schemas. The registry enforces compatibility rules: backward-compatible changes are allowed; breaking changes are rejected." What is a schema registry and what problem does it solve in event-driven systems?
Schema registry: a versioned catalog of message schemas that producers and consumers use to serialize/deserialize messages. Without it: the schema is embedded in producer code and consumer code independently — any mismatch causes failures. Confluent Schema Registry: stores Avro, Protobuf, or JSON Schema definitions. Each schema version has an ID. Producers include the schema ID in each message. Consumers fetch the schema by ID to deserialize. Compatibility modes: BACKWARD: new schema can read messages written with old schema. Consumers can upgrade first. (Safe default: add optional fields.) FORWARD: old schema can read messages written with new schema. Producers can upgrade first. FULL: both backward and forward compatible. NONE: no compatibility checking — dangerous. Schema format vocabulary: Avro: binary format with schema embedded. Compact, popular with Kafka. Schema defined in JSON. Protobuf: Google's binary format. Field numbers for backward compatibility. Excellent for gRPC (see grpc-protobuf exercises). JSON Schema: human-readable, widely understood. Larger payload size. CloudEvents standard: a CNCF specification for event envelopes — standardizes metadata fields (id, source, type, time, datacontenttype) while leaving the data payload to the application. Enables tooling interoperability across brokers. In conversation: 'Every team that owns a topic should register its schema on day one. Enforcing compatibility at the registry level stops breaking changes before they break production.'
4 / 5
An architect explains two EDA coordination patterns to the team: "For our order fulfillment flow, we considered two approaches. Choreography: each service listens for events and decides what to do. OrderPlaced → InventoryService reserves stock and emits StockReserved → ShippingService creates shipment and emits ShipmentCreated → NotificationService sends email. No central controller. Orchestration: a central saga orchestrator sends commands to each service in sequence and waits for replies. More control, single failure point. We chose choreography for scalability, but lost visibility — it's hard to see the full state of an order at any point." What is the trade-off between choreography and orchestration in event-driven architectures?
Choreography: services react to events without a central coordinator. Each service knows only its own trigger events and what it emits. Advantages: loose coupling, services are independently deployable and scalable. Disadvantages: the overall workflow is implicit — it exists only as a pattern of event flows. Hard to monitor, debug, or change. The "where is my order?" question requires correlating events across multiple topics. Orchestration: a central coordinator (saga orchestrator, Step Functions state machine, Temporal workflow) sends commands and waits for responses. Advantages: explicit, visible workflow; easy to monitor progress; simple to add compensation steps (rollback). Disadvantages: orchestrator knows about all services (coupling); single point of failure if not resilient. Saga pattern vocabulary: Saga: a long-running transaction composed of local transactions with compensating actions for rollback. Choreography saga: compensating events emitted by each service. Orchestration saga: coordinator sends compensation commands. Step Functions / Temporal vocabulary: Workflow: the definition of an orchestrated business process. Activity: an individual unit of work (an API call, a database update). Compensation: the undo action for a completed step. In conversation: 'Start with choreography for simplicity. Add an event-correlation service or upgrade to orchestration when debugging "where is my order?" becomes a weekly pain.'
5 / 5
A platform engineer compares messaging broker options for a new project: "We're evaluating Kafka versus SQS/SNS for our new event platform. Kafka is a distributed log — messages are retained for days or weeks, consumers can replay the history, and you can have multiple consumer groups all reading the same topic independently. SQS is a queue — messages are deleted after successful consumption. No replay. For our use case — multiple teams need to consume the same events, and we need replay capability for new consumers and data recovery — Kafka is the right choice. For simple task queues, SQS is fine." What is the fundamental difference between a message queue (like SQS) and a message log/stream (like Kafka)?
Message queue (SQS, RabbitMQ): competitive consumption model. Message is received by one consumer from the competing group. After acknowledgment, the message is deleted. Use for work distribution: N workers processing a task queue, each task done exactly once. No replay, no history. Message log/stream (Kafka, Kinesis, Azure Event Hubs): publish-subscribe with durable retention. Multiple consumer groups can read the same topic independently, each maintaining its own offset. Messages are retained for configured duration (hours to forever). New consumers can replay from the beginning. Use for event-driven integration, audit logs, stream processing, data pipelines. Broker comparison: Kafka: distributed log, partitioned, retained, consumer groups, replay, very high throughput. Operational complexity. SQS: managed queue, at-least-once, visibility timeout, DLQ, FIFO option. Simple. SNS: pub/sub fanout (broadcast to multiple SQS queues, Lambda, HTTP endpoints). Not a queue — no retention. RabbitMQ: traditional AMQP broker, flexible routing (exchanges, bindings), plugin ecosystem. EventBridge: AWS managed event bus, content-based routing rules, schema registry, cross-account. Use when source is AWS services or SaaS integrations. In conversation: 'If you need replay — to replay events for a new service, fix a consumer bug, or audit past behavior — you need Kafka or a log-based system. A queue can't give you that.'