skip to content

Your platform publishes one dashboard data source to several product teams - would you expose it per-subscriber or multicast, and why?

level: principalimportance: should knowfreq 38%

answer

  1. it is a contract, not a detail
  2. cost against coupling
  3. one sequence means one parameter set
  4. sharing later is additive, unsharing is not
  5. publish which kind each source is

basics

~20 s

Decide it as a published contract, not an implementation detail. Per-subscriber re-execution keeps consumers independent and parameterisable; one multicast sequence collapses cost but couples every consumer to one set of parameters, one failure and one lifecycle.

solid answer

~50 s

Treat it as a contract question: what does each consumer get, and what may they assume? A **per-subscriber** source re-runs the work for each consumer, which keeps parameters, failures, timing and cancellation independent - and multiplies upstream cost by the number of consumers. A **multicast** source gives everyone one sequence, which collapses cost and guarantees all consumers see the same values, at the price of one parameter set, shared fate on failure, and a lifecycle policy the platform now owns. The asymmetry decides the default: adding a sharing stage later is additive behind an unchanged shape, whereas a published live source cannot be turned back into per-consumer runs without breaking assumptions consumers have already built on it. So publish per-subscriber unless measured upstream cost, a quota, or a need for identical values across consumers argues otherwise - and where it does, publish a keyed set of shared sources with the lifecycle written down.

go deeper

for a junior

Understand the trade in one line: many independent runs cost more but stay independent, while one shared run is cheap and couples its consumers together.

for a middle

Name the concrete consequences of sharing - one parameter set, one failure for everyone, a different experience for a late consumer - rather than describing it as deduplication.

for a senior

Bring measurement: executions per session, upstream quota, parameter spread and attach churn, and turn the shared run's lifecycle into an explicit policy rather than a default.

for a principal

Own the reversibility argument and the contract. Sharing later is additive; unsharing is not, so publish the weaker guarantee first and state for every published source which kind it is.

## What is actually being decided The choice looks like an implementation detail and is not. It determines, for every consuming team, how many times their subscription costs the platform, whether they may ask for their own parameters, whether another team's failure ends their sequence, and what they see when they attach late. Those are contract terms, and consumers will build on them whether or not they are written down. ## The case for one shared sequence - **Upstream cost stops scaling with consumers.** If the work is a paid call, a rate-limited endpoint or an expensive aggregation, per-consumer re-execution multiplies it by a number you do not control. - **Everyone sees identical values.** Where consumers compare notes - two panels that must agree, a view and the alert that fires from it - independent runs at slightly different times produce defensible but embarrassing disagreements. - **One connection, one warm path.** Startup cost, authentication and any per-run setup are paid once rather than per consumer. ## The case for per-consumer runs - **Parameters.** One sequence carries one set of arguments. The moment consumers need different filters, ranges or tenants, a single shared source stops being expressible and you need one per parameter set anyway. - **Blast radius.** A shared sequence gives shared fate: one upstream failure or completion ends it for everyone attached, at the same instant. Independent runs fail one consumer at a time. - **Freshness on demand.** A consumer that attaches gets data as of its own subscription, rather than whatever the shared run last produced. - **No lifecycle to own.** Nobody has to answer what happens at zero consumers, how long a grace period should be, or how much to retain for a newcomer. | Dimension | Per-subscriber | One multicast sequence | |---|---|---| | Upstream cost | scales with consumers | flat in consumers | | Parameters | per consumer | one set; keyed sources for more | | Failure | isolated to one consumer | shared by all attached | | Late attach | full sequence from its own start | only what follows, plus any retention | | Lifecycle | none to own | start, stop, grace and retention policy | | Agreement between consumers | values may differ by timing | identical by construction | ## The asymmetry that should set your default These options are not equally reversible. - Going **from per-subscriber to shared** is additive. The published shape stays the same, a sharing stage appears behind it, and consumers see fewer executions and values that now agree. The visible change is that failures become shared and late attachment behaves differently - real, but manageable, and announceable. - Going **from shared back to per-subscriber** is not a refactor. Consumers have built on identical values, on flat cost and on whatever a newcomer receives. Splitting them into separate runs multiplies upstream cost overnight and lets consumers disagree, which is precisely what some of them stopped guarding against. So the cheaper mistake is publishing per-subscriber and sharing later. Publish live early and you have committed every consumer to shared fate before anyone measured whether they needed it. ## The evidence to bring A decision defended with numbers beats one defended with preference. Gather: 1. **Executions per session today**, and the ratio of executions to distinct viewers - that is the multiplier sharing would remove. 2. **The upstream bill**: quota, per-call cost, and the latency of the work at the concurrency per-consumer runs actually produce. 3. **The parameter spread**: how many distinct argument sets consumers use. A long tail means keyed shared sources, with their own cardinality problem, rather than one sequence. 4. **Correlation requirements**: which consumers must agree with each other, stated by the teams rather than assumed. 5. **Attach and detach churn**, because it decides whether a reference-counted shared run would thrash and whether a grace period is needed. 6. **Freshness tolerance**: whether a consumer may render a retained value, and how old it may be. ## A defensible position A reasonable standard for a platform team: publish per-subscriber by default; share where measurement shows the multiplier is real or where consumers must agree; when you share, publish a keyed set of shared sources so parameters survive, and write the lifecycle into the contract - what happens at zero consumers, what a newcomer receives, and whose failure ends whose sequence. Add one rule that costs nothing and prevents the worst outcome: **state which kind each published source is**, because a consumer cannot tell by looking, and every assumption they make about cost, freshness and blast radius depends on the answer.

  • Consumers need the same feed with different filters - does sharing survive that?
    Only as a keyed set: one shared sequence per distinct parameter set, created on demand and released when its own consumers leave. That preserves the cost saving where consumers genuinely overlap, but it adds a cardinality problem - a long tail of rare parameter combinations degrades back towards per-consumer runs with extra machinery.
  • How would you make the change from per-subscriber to shared safe for teams already consuming it?
    Announce the two visible differences before shipping: failures become shared, so one upstream error ends every consumer's sequence at once, and a late attach no longer starts its own run. State what a newcomer will receive, roll it out behind a switch you can reverse, and watch upstream executions and consumer error rates across the change.
  • What tips the decision when the upstream work is cheap but consumers must agree with each other?
    Agreement wins. Identical values across consumers is something only one shared sequence gives by construction; with independent runs you would be reconciling defensible disagreements forever. Cost is then not the argument - correlation is - and the lifecycle should favour continuity, such as an eagerly started run, over stopping at zero consumers.

saying these in an interview costs you the question

  • Treats sharing as an optimisation flag with no contract change
  • Ignores that one shared sequence carries one parameter set
  • Overlooks shared fate when a single upstream failure occurs
  • Assumes a published live source can be split back later cheaply
  • Decides from preference without measuring executions per session
  • Leaves the zero-consumer policy unstated in the published contract