Why this matters: broker follow-ups probe whether you understand the contracts you implemented, not just the mechanics. Each variation below either deepens a promise the core design made or adds a consumer pattern on top of its seams — and each has a cost you're expected to name unprompted. The skill being tested is the same as lesson 2's: extend by placement, and price every promise.
What at-least-once really does to the queue
The core design put acks in as a mode flag; the follow-up pressure-tests whether you know what they cost. In at-most-once, a message's life ends at the callback — the queue only ever holds the undelivered. In at-least-once, delivered-but-unacked messages live on in pending state, so the subscription's memory footprint is queue plus pending — and a subscriber that processes but forgets to ack grows pending without bound while its queue looks healthy. That means the ack path needs its own hygiene: an ack timeout that moves stale pending messages back to the queue for redelivery, which is also your crash story — a subscriber that dies mid-processing gets its in-flight message redelivered after the timeout. Own the sharpened duplicate consequence: timeout-triggered redelivery will re-send messages whose processing actually finished, so "subscribers must tolerate duplicates" hardens from a caveat into a design requirement on every at-least-once consumer. And say the ordering fine print like an operator: redelivery re-enqueues at the tail, so a redelivered message arrives after messages published later — strict per-topic order holds for the smooth path, and redelivery is the documented exception.
Competing consumers: one queue, many workers
So far every subscriber gets every message. The next thing real users ask for is the opposite: N workers sharing a workload, each message processed by exactly one of them. This is a different subscription shape, not a broker rewrite: a consumer group is one subscription — one bounded queue, one entry in the topic's list — with multiple workers draining it. Fan-out to groups, fan-in within one. The cost to name before the interviewer does: with several workers pulling from one queue, per-subscriber ordering is gone — two consecutive messages process concurrently on different workers and complete in either order. That isn't a bug; it's the trade — parallel throughput bought with the ordering promise. If the group needs order per key (all events for user X in order), sketch the standard middle ground: hash the key over the group's workers so each key's messages land on one worker — order within a key, parallelism across keys. Groups slot into the existing model precisely because the Subscription owns its queue: the group is just a subscription whose "worker" is plural, and the mode/ack machinery rides along unchanged.
Hierarchical topics — the direction sketch
"Subscribe to orders.*" arrives eventually. Sketch the seam, not the build: topics gain path structure (orders.eu.created), and a subscription may carry a pattern instead of an exact name. The design decision worth stating is where matching happens: at subscribe time, resolve the pattern against existing topics and also register it so newly created topics check pending patterns — making publish stay O(subscribers) — versus at publish time, matching every pattern on every publish — simpler, but the hot path pays O(patterns). Name the resolve-at-subscribe answer as the scalable one, note that pattern registration now races topic creation (the same copy-on-write discipline applies), and stop. The full build is a chapter of its own; the seam and the cost placement are the interview answer.
Metrics: making the contracts observable
Every promise the broker makes is invisible until it breaks — so instrument the promises themselves. The counters that matter, all per-subscription and all already cheap because the subscription owns its state: queue depth (how far behind is this subscriber right now), drop count (how much has the bounded queue discarded — lesson 3's counter, surfaced), pending count (at-least-once: how much is delivered but unacked), and delivery age (time from publish to callback — the lag a consumer actually experiences). Then say what each one diagnoses: rising depth with flat drops means the subscriber is slowing; rising drops means it's overwhelmed and losing its oldest backlog, exactly as contracted; ballooning pending means acks are missing, not processing. A broker whose failure modes are all countable turns "it's losing messages!" from an argument into a dashboard read — and offering that unprompted reads as operational scar tissue, the good kind.
What ordering buys — and what it costs
The deepest follow-up: why promise order at all? Price both sides. The per-topic promise costs one sequencing point — publishers on a hot topic serialize through it — and one-worker-per-subscription, which caps a single subscriber's drain rate at one core. Drop the promise and both limits vanish: publishers fan out lock-free, workers multiply per subscriber — that's the competing-consumers trade generalized. Keep it, and consumers get the property that makes stateful logic simple: "state-changed" events apply cleanly because they arrive in the order they happened. The mature answer isn't picking a side — it's noting the contract is per subscription already: order-sensitive consumers take the single-worker guarantee, throughput-hungry ones take a group and handle disorder. The broker's promises were priced per subscriber from the start; that's the design paying out one last time.
Key takeaway
Each follow-up prices a promise: at-least-once costs pending state, ack timeouts, and duplicates hardened into a requirement (with redelivery as ordering's documented exception); competing consumers buy parallelism by spending per-subscriber order, recoverable per key via hashing; hierarchical matching is a subscribe-time-resolution sketch; metrics instrument the contracts themselves — depth, drops, pending, delivery age — so every failure mode is countable. When a broker follow-up lands, name the promise it touches and the price of keeping it.