Skip to content
10 chapters · 205 minutes

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.

  1. 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.
  2. 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)
  3. 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
  4. 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.

  1. 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
  2. 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
  3. 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.

  1. 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
  2. 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
  3. 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