Messaging
Handing off work between services without losing it: queues, logs, and delivery guarantees.
Explainers
- Design a Chat System — Two people, a message, and the expectation that it arrives instantly, in order, and never vanishes — even when the recipient is in a tunnel. Built from one polling request up to a stateful WebSocket fleet over a durable inbox: the commit-first envelope that sizes everything by open connections (not requests), the honest transport fork (short poll vs long poll vs WebSocket), a session registry that finds a user across the fleet, store-then-notify with per-recipient inbox queues, Snowflake IDs because created_at collides, a bucketed key-value store for history because reads are long-tailed, the signature offline-delivery exhibit where a per-device cursor replays exactly the gap, presence via heartbeat + flap-suppression + pub/sub fanout, and a failure sweep whose surprising box is a chat server dying with all its connections.
- Design an Email Service — A billion users, forty messages a day each, kept forever — email is a storage problem wearing a messaging problem’s clothes, and almost none of it is under your control once a message leaves the building. Built from zero: a commit-first envelope that lands on the yearly petabytes, the send and receive pipelines threaded through queues so a slow recipient never blocks anyone, the mailbox data model at the heart — partition by user, folders, time-ordered message IDs, and the honest read/unread denormalization a wide-column store forces on you (two tables, move the row) — the search index as its own write-heavy LSM, and deliverability as its own discipline: IP reputation, dedicated-IP warm-up, SPF/DKIM/DMARC in a breath each, and the bounce/complaint feedback loops — then the failure sweep whose sharpest box is your own IP landing on a blocklist.
- Design a Notification System — One event — “your driver is arriving” — has to reach a phone, and you own almost none of the road: the last mile belongs to Apple, Google, Twilio, and an email provider, and none of them promises the message arrives. Built from zero: a commit-first envelope on 10M push + 1M SMS + 5M email a day, why one inline sender collapses, the fan-out core where a single event lands in one queue per channel so a Twilio outage never blocks a push, the device-token table and the templates / user-settings / rate-cap layers that keep you from spamming a real person, the reliability spine (persist-then-queue, retry with backoff, and the honest at-least-once truth that dedupe reduces but cannot erase), the open/click tracking loop — then the failure sweep whose quietest box is a compliance bug that ships a notification to someone who opted out.
- Build a Report and Fan It Out to Millions — One prompt hiding two systems: a periodic batch pipeline that computes 20 million personalized reports, joined to a delivery ramp that mails every one inside a 3-hour window over a provider you don’t own. Built from zero: the scope split (compute vs deliver), a commit-first envelope where a ~2,000/s send ceiling barely clears the deadline, the naive cron loop and why it dies, the compute DAG with a pinned snapshot and per-task retries, the central precompute-vs-render-on-open deliberation tuned to the open rate, rendering to immutable artifacts behind short-lived signed links, then the delivery half — batching, a token-bucket rate shaper clamped to the provider ceiling, idempotency keys so nobody gets the report twice, suppression before the send, a checkpointed cursor so a crash resumes instead of restarting, and a live completion burn-down that proves all N went out by when. Distinct from a notification system (linked, not duplicated): this is the report COMPUTE joined to the delivery ramp.
- Design a Distributed Message Queue — How services hand work to each other through a queue that never loses a message. Start with one sender and one receiver; grow it until it survives crashes and slow consumers — drawn and animated.
- Design a Webhook & Trigger Delivery Platform — Thousands of customer servers, each unpredictable — slow, offline, flaky at 3am — and one bad one must never touch the rest. We compute the fan-out arithmetic (events → deliveries, retry amplification when 5% of endpoints are down, storage for a 3-day retry horizon), watch a naive POST-in-the-request-loop stall on a single slow endpoint, then build the real design one mechanism at a time: a durable queue off the request path, HMAC signature verification in both directions, per-endpoint token buckets, a jittered retry ladder to a dead-letter queue, honest at-least-once semantics, and ordering that costs only the customer who asked for it — closing on Stripe, GitHub, and Svix's own published numbers.