Module Quiz
Complete this quiz after finishing all concept and practice pages.
Current Module Questions
Question 1: What Is an Event?
State, in one sentence, the three non-negotiable properties of an event, and give one example of a "message" that is not an event and why.
Answer: An event is past tense, immutable, and authored by the system that knows it happened. SendWelcomeEmail is not an event: it is imperative (a command to a specific handler), not a fact, and its consumer count is one, not many.
Common Errors:
- Confusing "past tense" with "past timestamp" -- any old CRUD row has a timestamp; only an event is named by the domain transition.
- Accepting
OrderUpdatedas an event -- it is a summary, not a specific fact; it erases which transition occurred.
If You Got This Wrong:
- Review Concept 01.
Question 2: Event vs Command vs Query
A team proposes a topic called order-events carrying PlaceOrder, OrderPlaced, GetOrderStatus, and CancelOrder. Identify each message's real intent and propose the corrected topic/endpoint for each.
Answer:
PlaceOrder-> command -> queuepayment.commandsor HTTP endpoint; single consumerOrderPlaced-> event -> topicorder.placed; pub-subGetOrderStatus-> query -> HTTP/gRPC endpoint; never on a brokerCancelOrder-> command -> queueorder.commandsor HTTP endpoint
Mixing them on one topic hides intent and forces future engineers to add "only one consumer please" comments.
Question 3: Pick the Messaging Pattern (Scenario 1)
A checkout service publishes that an order was placed; four other services react (billing, inventory, notifications, analytics). Which messaging pattern and why?
Answer: Publish-subscribe topic. Each subscriber reacts independently; adding fraud-detection as a fifth subscriber next month must not require changes to the publisher. Point-to-point queue would give the message to only one consumer; work-distribution semantics here would be wrong.
Question 4: Pick the Messaging Pattern (Scenario 2)
An image-processing service accepts upload events and generates thumbnails. 10 workers share the load. Which messaging pattern and why?
Answer: Point-to-point queue (work distribution). Each image is a task that exactly one worker should process. Pub-sub would cause every worker to regenerate the same thumbnails -- both wasteful and potentially corrupt (race on storage). Scale is adding workers sharing the queue.
Question 5: The Outbox Pattern
A service writes to Postgres and then publishes to Kafka. Sometimes, after a crash, the DB has the row but the broker does not have the event. Name the bug and describe the fix.
Answer: This is the dual-write bug. The DB transaction and the broker publish are not atomic; a crash between them loses the event. The fix is the transactional outbox: inside the same DB transaction, insert a row into an outbox table containing the event. A separate relay process reads unpublished outbox rows, publishes them (at-least-once) to the broker, and marks them published. Either both the state change and the outbox insert happen, or neither does.
Question 6: Queue vs Log-Based Broker
A team argues about RabbitMQ vs Kafka for "an event bus." What two questions decide the choice?
Answer:
- Do multiple independent services need to read the same stream? (If yes, log-based; queues are point-to-point.)
- Do you need replay -- rebuilding a read model, catching up a new consumer, reprocessing after a bug? (If yes, log-based; queues discard on ack.)
If neither is true, a queue is often operationally cheaper and simpler.
Question 7: Partitions and Consumer Groups
A Kafka topic has 12 partitions. A consumer group has 20 consumers. What happens?
Answer: Only 12 consumers get a partition assignment; the remaining 8 are idle. Consumer count beyond partition count adds no parallelism within a group. To scale further, increase the partition count (disruptive for keyed topics) or redesign for more concurrent work per partition.
Question 8: Ordering Guarantees
A saga orchestrator occasionally sees PaymentCaptured before OrderPlaced. List the two most likely causes.
Answer:
- Inconsistent key across topics.
order.placedandpayment.capturedare partitioned by different keys (or by no key at all), so events for the same order hit different partitions and consumer instances. - Consumer commits offsets before processing, then crashes and skips messages on restart -- out-of-order delivery relative to the orchestrator's state.
Fix: partition all saga-relevant topics by the same key (usually the aggregate ID), and commit offsets after processing.
Question 9: Choreography vs Orchestration
A 20-step business workflow with timers, compensations, and several human approvals needs to be modeled across 12 services. Which topology and why?
Answer: Orchestration. At 20 steps with timers and compensations, the workflow state itself is a business-critical artifact. Orchestration (Temporal, Step Functions, Camunda) makes the state machine explicit, handles timers and retries declaratively, and gives support staff a single place to see "where is instance X stuck?" Choreography across 12 services with that many steps produces a graph that no one can reason about or debug.
Question 10: Saga Compensation
In a checkout saga ReserveStock -> ChargeCard -> CreateShipment, CreateShipment fails. Walk the compensation.
Answer:
- Orchestrator runs
RefundCard(order_id)->PaymentRefundedevent emitted. - Orchestrator runs
ReleaseStock(order_id)->StockReleasedevent emitted. - Orchestrator marks the saga
compensatedand emitsOrderCancelled(reason=shipment_failed).
Compensations run in reverse order of original steps, each is idempotent, and the payment "rollback" is a new, named event (PaymentRefunded), not a database rollback -- the charge already committed.
Question 11: Idempotency and Exactly-Once
Explain why "at-least-once delivery + idempotent consumers" is effectively exactly-once, and why stronger broker-level "exactly once" is not enough.
Answer: The broker can guarantee at-least-once delivery to the consumer, but once the consumer performs a side effect on an external system (DB write, API call, email send), the broker cannot participate in that system's commit. A crash between the effect and the offset commit causes a redelivery; without consumer-side idempotency, the effect is repeated. "Effectively exactly-once" is achieved at the system level: at-least-once delivery, a dedup key (usually event_id), and the effect + dedup-insert in one transaction. Kafka's EOS applies to Kafka-to-Kafka pipelines only; crossing to any external system returns you to the at-least-once + idempotency model.
Question 12: Event Sourcing Fit
Name three situations where event sourcing is overkill, and one where it is the natural fit.
Answer:
- Overkill: (1) a simple internal CRUD tool where history is uninteresting; (2) a team with no prior event-sourcing experience under tight deadlines; (3) a system whose primary access pattern is ad-hoc analytical queries.
- Natural fit: a regulated domain (insurance claims, clinical records, financial ledgers) where audit is a hard requirement, business analysts frequently ask "what did we know on date X?", and multiple read shapes (dashboards, fraud, reporting) coexist.
Question 13: Projections and Rebuildability
Why is it important that every projection be rebuildable, and what does that require of the event stream?
Answer: Rebuildability lets you fix bugs in projection logic, evolve read-model schemas, and add new read models without manual migrations -- you reset the consumer offset to zero and re-consume. This requires the event stream to retain events for at least as long as you need to rebuild any projection. A 7-day Kafka retention cannot rebuild a 2-year projection; for long rebuild horizons, use long retention, log compaction, or a dedicated event store.
Question 14: CQRS Decision
A 5-engineer startup with 2 simple CRUD screens and ~100 customers asks if they should use CQRS. Defend a recommendation.
Answer: No. CQRS is not justified here. The commitments -- eventual consistency on reads, extra deployable components (projections, read stores), more operational complexity (lag monitoring, rebuilds) -- have no matching benefit: there are no distinct read shapes, no heavy read workload, no regulatory audit requirement, and the write side has no complex invariants. Use a single Postgres DB, maybe a materialized view or two, and revisit CQRS when (a) the team grows, (b) read workloads diversify, or (c) event-driven infrastructure is already in place for other reasons.
Question 15: Integration Question -- Tie the Module Together
A payments service emits PaymentCaptured. Downstream: a ledger service, a notification service, and an analytics pipeline. Describe the minimum production-quality integration end-to-end.
Answer:
- Producer side:
PaymentCapturedis an immutable past-tense event withevent_id,occurred_at,order_id,amount_cents. Written via outbox pattern in the same DB transaction as the payment record; a relay publishes to a Kafka topicpayment.capturedpartitioned byorder_id. - Topic design: log-based broker (Kafka) so all three consumers can read independently; retention = 14 days for replay margin; replication factor 3.
- Consumer side: each downstream service runs its own consumer group (
ledger,notifications,analytics). Each consumer is idempotent, dedupe-keyed onevent_idwith a dedup store that outlives the worst-case redelivery window. Offsets are committed after processing. - Workflow: no central orchestrator here; this is reactive fan-out (choreography). If a broader saga exists (e.g., the charge is part of an order workflow), the orchestrator consumes
PaymentCapturedas one of its inputs. - Observability: correlation IDs flow on every event; dashboards show outbox lag and consumer lag per group.
Interleaved Review Questions
(5 questions from previous modules to maintain retention)
Prior Module Question 1 (from S8M2)
What is a "distributed monolith," and what is the single most reliable signal that a microservices system has become one?
Answer: A distributed monolith is a system split into multiple services that must be deployed and changed together -- the network separation is real but the modular independence is not. The reliable signal is coordinated deploys: every meaningful feature requires simultaneous releases of 3+ services; a change to one service cannot be deployed in isolation without breaking another.
Prior Module Question 2 (from S8M1)
In system design, what is the correct first step when a requirement is ambiguous -- and why not "start drawing components"?
Answer: Clarify requirements and constraints: users, scale, latency, consistency, failure tolerance. Drawing components before the ambiguity is resolved forces decisions that cannot be defended and then calcifies into premature architecture.
Prior Module Question 3 (from S7)
State the dependency rule in Clean Architecture in one sentence.
Answer: Source code dependencies point only inward, from concrete outer layers (frameworks, drivers) toward abstract inner layers (entities, use cases) -- never the other way.
Prior Module Question 4 (from S6)
What does "eventual consistency" actually promise, and what does it explicitly not promise?
Answer: Eventual consistency promises that if writes stop, all replicas will converge to the same value. It does not promise any particular ordering of intermediate reads, nor a bounded staleness window, unless the system additionally offers specific session or monotonic-read guarantees.
Prior Module Question 5 (from S5)
Why does a queue between a fast producer and a slow consumer not "solve" the throughput mismatch -- and what does it actually buy you?
Answer: The queue cannot make the consumer faster; if the producer sustains a higher rate than the consumer, the queue grows without bound. What the queue buys is smoothing of bursts (the consumer handles peaks over time) and back-pressure decoupling (producer does not block on consumer), plus durability (consumer crashes do not lose work). Long-term throughput is still consumer-limited.
Self-Assessment and Remediation
Scoring and Advancement Criteria
Mastery Level (90-100% correct):
- Status: Ready to advance to next module
- Action: Proceed to Module 4 (Scale, Reliability & Performance)
Proficient Level (75-89% correct):
- Action: Review concept pages corresponding to missed questions; redo the matching kata.
Developing Level (60-74% correct):
- Action: Rework Clusters 2 (messaging + outbox) and 4 (saga + idempotency). These are where most missed questions will cluster. Redo Practice 2 and 3 fully.
Insufficient Level (<60% correct):
- Action: Return to Concepts 1-3 and rebuild the mental model before attempting the operational clusters. Without the "event is a past fact" discipline, the rest of this module does not stick.
Remediation Resources by Score Range
75-89% Score Range:
- Targeted Review: Re-read only the specific concept(s) behind missed questions.
- Quick Practice: 2-3 additional scenarios from Practice 2 or 4.
60-74% Score Range:
- Systematic Review: Full re-read of Clusters 2 and 4.
- Extended Practice: All of Practice 3 (saga + idempotency) with different domains.
- Alternative Explanations: Fowler's "What do you mean by Event-Driven?" and Richardson's saga article on microservices.io.
<60% Score Range:
- Foundation Check: Verify S7M2 (event-driven topologies) is understood.
- Comprehensive Remediation: Rework every concept page with notes in your own words.
- Peer/Instructor: Explain "event vs command" and "the outbox pattern" out loud; the gap will surface quickly.