The chapters
Work through them in order. Each chapter explains an idea, hands you a case that gets it wrong, and ends with a check that the message still arrives once the bug is gone.
Part 1Delivering once
4 chapters, 80 minutes
Send only what happened, never twice, and retry only what can succeed, without a storm.
- 0120 min
Send after commit: the outbox
A notification is a promise about something that happened. Send it only once that thing has really happened, and make sure it is still sent if the process dies a moment later.
fay@example.com was told they joined ws_orbit. They did not. - 0220 min
Once, even when you retry
A timeout does not mean the request failed. It means you do not know. Retries are only safe when the receiver can recognise a repeat, and that takes a key that is the same on every attempt.
ada@example.com got 4 (should get 1) - 0320 min
Errors that never heal
Retrying is right for a provider that is busy or broken, and wrong for an answer that will never change. Read the status code before you retry.
tok_1042_old requests: 16 - 0420 min
Backoff and jitter
Exponential backoff spreads one client's retries over time. It does nothing for a thousand clients that failed at the same moment: they back off together and come back together. Jitter breaks them apart.
busiest second after recovery: t=31 s, 1000 requests (10.0x capacity)
Part 2Delivering right
3 chapters, 60 minutes
The latest state in the right order, only to people who want it, when they are awake.
- 0520 min
Out of order
Queues reorder messages, and the clocks of different machines disagree. Order state changes by a sequence number from the system that owns the state, and drop anything older than what you have already shown.
card says: building the truth: live - 0620 min
Preferences and consent
A user's choice applies to every message sent after they make it, including messages you queued before. Check preferences at the moment you send, and keep required account notices out of the user's off switch.
marketing sent after an unsubscribe: 2 - 0720 min
Quiet hours and time zones
"Not between 22:00 and 07:00" means on the user's clock. A server that checks its own clock in UTC wakes up half the world.
made 03:05 sent 03:05 Priya commented on your pull request. <- buzzed in quiet hours
Part 3Delivering at scale
3 chapters, 65 minutes
Batch without silence, keep urgent messages fast, and trust what providers tell you.
- 0820 min
Batching without silence
A digest that waits for a quiet moment never goes out for your most active users. Every batching rule needs a maximum wait that counts from the first update, not the last.
longest wait: 604 minutes - 0920 min
Priority lanes
A sign-in code that waits behind six thousand announcements is useless by the time it arrives. Messages that a person is waiting for need their own lane.
It arrives 115.0 s later: expired before it arrived - 1025 min
Webhooks you can trust
A valid signature proves who sent a request, not when. A captured request stays valid forever unless you check its timestamp and refuse a webhook id you have already handled.
replays accepted: 200 of 200