Free preview

Why this matters: an in-process pub-sub broker sounds like a map of lists with a for-loop over callbacks — and that's exactly what a weak round produces. The real problem is the promises: who receives what, in what order, and what the broker guarantees when things go wrong. Those promises aren't in the prompt; they come out of the requirements conversation, and one of them — the delivery guarantee — is the question this round is really grading.

The prompt, as given

Design an in-process publish-subscribe message broker.

Publishers send messages to named topics; subscribers register interest and receive them. It's a library other code embeds — not a distributed system, not Kafka — but inside one process it still has to keep its promises about who receives what, and in what order.

The prompt disclaims distribution twice, and believe it: no partitions, no networked consumers, no durability across restarts. What's left is the essential broker — and the essential broker is a concurrency-and-contracts problem, which is harder to get right than it is to make big.

The questions, and why each one matters

"What delivery guarantee am I making — if a subscriber's callback fails, is the message gone?" This is the defining question of the round, and it's yours to raise; interviewers deliberately wait to see if you do. The two honest contracts: at-most-once — fire and forget, a failed delivery is a lost message, no tracking; and at-least-once — delivery is tracked until the subscriber acknowledges, failures are redelivered, and duplicates become possible. Neither is "correct"; what's graded is whether you name the choice, pick per the use case (the representative set below allows choosing per subscriber), and own the consequence out loud — at-least-once means acks and duplicate handling, at-most-once means silent loss on failure. Never raising the question is the single biggest gap you can leave in this round.

"What ordering do I promise?" The representative answer: messages on a topic have a publish order, and each subscriber receives a topic's messages in that order — but there is no ordering promise across topics. Getting this answer precisely matters because ordering is expensive exactly where you promise it: per-topic order will force a single sequencing point per topic, and the absence of cross-topic promises is what keeps topics independent and the design parallel.

"Is this a library in the caller's process, or a server?" A library: publishers and subscribers are objects in the same program, topics are plain names created on first use, and nothing survives a restart. This answer kills several tempting overbuilds — serialization, wire protocols, persistence — before they start.

"Whose thread runs a subscriber's callback?" The sleeper question. Publishers call publish from any thread; if the broker runs callbacks on the publisher's thread, then a slow subscriber stalls the publisher and every later subscriber in the list — one bad callback and the whole program convoys. The representative answer: callbacks run on the broker's own delivery machinery, never the publisher's thread. Hold onto this; lesson 2 turns it into the design's central claim.

"What happens when a subscriber can't keep up?" The given contract: each subscription gets a bounded queue with per-subscription capacity, and when it's full the oldest message is dropped. Take the answer as a spec and move on — your job in this round is to implement that contract cleanly, and to be able to say plainly what it implies: a subscriber that lags loses its oldest backlog first.

"What's out of scope?" Wildcards, topic filters, priorities: all out of scope. Clean boundaries — note them and don't build toward them.

The requirement set this chapter builds against

Shape       in-process library; same-program objects; topics are
            plain names, created on first use; nothing durable
Delivery    per-subscriber choice: at-most-once (fire and forget)
            or at-least-once (tracked until acked; duplicates
            possible on redelivery)
Ordering    per-topic publish order, delivered to each subscriber
            in that order; NO promise across topics
Threading   publish callable from any thread; callbacks run on
            the broker's delivery machinery, never the publisher's
Slow subs   bounded queue per subscription (capacity is per-
            subscription config); when full, oldest is dropped
Out of      wildcards, topic filters, priorities
scope

Each row is a constraint with teeth: the threading answer forbids the naive for-loop-over-callbacks; per-topic ordering forces a sequencing decision; the delivery choice splits the subscription type in two behaviors; and the bounded queue is a contract your enqueue path must implement exactly.

As throughout this course: a live interviewer's answers may differ from this set — perhaps their broker promises no ordering at all, or a single global delivery mode. The conversation is the skill; a different answer sheet steers the same method somewhere slightly different.

Key takeaway

The broker's design is dictated by promises you must extract: the delivery guarantee (at-most-once versus at-least-once, chosen per subscriber, consequences owned aloud — raising this unprompted is the round's biggest signal), per-topic ordering with nothing promised across topics, callbacks on the broker's machinery rather than the publisher's thread, and a bounded per-subscription queue that drops oldest when full. Pin all four before designing; each one eliminates a category of wrong design.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue