Skip to content
tezvyn:

Guarantee at-least-once delivery for a critical event?

Source: microservices.ioHardHow cards are made

Guarantee at-least-once delivery for a critical event?

This tests your grasp of atomicity without 2PC. A great answer outlines the Transactional Outbox pattern: write the event to a DB table in the same transaction as the business logic, then use a relay process. A red flag is relying on simple try/catch blocks.

What's really being asked

This question tests your understanding of atomicity between a database write and a message send, a classic distributed systems problem. The keywords "guarantee" and "financial transaction" signal that data loss is unacceptable. The interviewer is looking for a design that survives process crashes and network failures without using a distributed transaction (2PC), which is often impractical.

The full answer

First, identify the core challenge: a service can crash after committing its database transaction but before successfully sending the event, leading to lost data. Second, propose the Transactional Outbox pattern. The application service writes its business data and the event payload to an 'outbox' table within the same, single, local database transaction. This makes the state change and the intent to send the event atomic. Third, describe the 'Message Relay', a separate process or thread that reads from the outbox table and sends the events to the analytics backend. Fourth, explicitly state that this pattern creates an at-least-once delivery guarantee. The relay could crash after sending but before marking the event as sent, causing a duplicate on restart. Therefore, the consuming analytics service must be idempotent, for example by de-duplicating based on a unique event ID.

The mistakes people make

Sending the event after the database commit is the most common flaw. This creates a window for failure where the event is lost if the service crashes. Sending the event before the commit is also wrong; the event may be sent, but the transaction could roll back, leading to an event for an action that never happened. Suggesting 2PC is another red flag, as it's often unsupported, couples services tightly, and has performance penalties. Finally, a candidate who describes the outbox pattern but fails to mention the need for consumer idempotency has an incomplete understanding of its trade-offs.

What usually comes next

How would you implement the message relay? (Polling Publisher vs. Transaction Log Tailing). How do you prevent the outbox table from growing infinitely? (The relay must delete or update rows after a confirmed send). What happens if the analytics backend is down for an hour? (The outbox acts as a durable buffer; the relay will catch up when the service is back online). How do you ensure event ordering? (The outbox table should have a timestamp or sequence number, and the relay should process events in that order).

A concrete example

A payment service processes a transaction. In a single DB transaction, it inserts a row into the payments table and another row into the outbox_events table with the event payload. A separate message relay process polls the outbox_events table every 200ms for new events. It fetches a batch of up to 100, sends them to the analytics Kafka topic, and upon receiving acknowledgement from the broker, it deletes the corresponding rows from the outbox_events table. If the relay crashes, it simply restarts polling from where it left off, potentially re-sending some events.

Interview question

What is the primary benefit of using the Transactional Outbox pattern for critical event publishing?

  • a.It eliminates the need for consumers to implement idempotency logic.
  • b.It simplifies distributed transaction management using two-phase commit.
  • c.It ensures exactly-once delivery of events to all consumers.
  • d.It guarantees atomicity between a local database transaction and event publication.Correct
Why?

The Transactional Outbox pattern ensures that the business data update and the intent to publish an event are atomic by writing both to the same local database transaction. It provides at-least-once delivery, not exactly-once, and therefore requires consumers to be idempotent, making option C and B incorrect. The pattern is specifically designed to avoid the complexities and drawbacks of two-phase commit, making option B incorrect.

Just read this? Test yourself on what you have been reading.

Read the original → microservices.io

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on system design — each one lists the topics its interview covers.

See open roles