Your outbox relay published twice. Is the outbox design broken?
After this you can answer: Your outbox relay published twice. Is the outbox design broken?
Say it in 30 seconds
Section titled “Say it in 30 seconds”The deeper answer
Section titled “The deeper answer”The outbox promises that a committed booking retains an event to deliver. It does not promise one network publish. A lost SNS response can be ambiguous too: the relay sees a failure even if SNS accepted the request.
The relay uses stable identifiers from the stored payload and validates that they match its outbox row. Consumers should deduplicate the business operation. The email worker uses booking.confirmed plus the booking ID, rather than depending on the transport message ID. The ticket worker derives one ticket ID per booking seat.
For production, I would monitor publish failures, pending-row age and consumer completion separately. A growing outbox might mean a policy denial, topic misconfiguration or a database problem, not just harmless retries. Delivery is only useful when the downstream effect eventually happens, and the email consumer still has documented duplicate windows around its external send.
Counter-questions
Section titled “Counter-questions”Why keep row locks while calling SNS?
What if marking the row sent fails?
Can a FIFO queue solve the whole problem?
Where in MiniTickets
Section titled “Where in MiniTickets”Read Outbox, then inspect the outbox piece →.
apps/api/src/queries/outbox.ts → deliverBatch
Rehearse the consumer limit with the duplicate-email case.
Read this book online: https://book.theversehub.in/