skip to content

In emergent design, which decisions must still be made deliberately up front, and how do you decide?

level: principalimportance: should knowfreq 44%

answer

  1. Two questions: reversibility and reachability
  2. Can a green commit series reach it
  3. Stored shapes, boundaries, contracts, authorities
  4. Thinnest possible skeleton, everything inside emerges
  5. Each up-front decision is a hypothesis with a trigger

basics

~20 s

Decide by reversibility and reachability. Anything a later restructuring can reach inside code you own — unit shapes, module internals, names — let it emerge. Stored data shapes, process boundaries, contracts other teams consume and cross-cutting authorities get decided deliberately.

solid answer

~50 s

Emergent design is a claim about structure a restructuring step can reach, so I ask two questions of every decision: what does reversing it cost once there is production data and other consumers, and can it be changed inside code I own in commits that each stay green? Unit shapes and module internals pass both, so they emerge. A persisted data shape, a boundary between processes, a published contract and a cross-cutting authority such as the source of time fail one or both — retrofitting those is a migration and an audit of every call site, not an extraction. So I decide the thinnest possible skeleton of those deliberately and let everything inside it emerge, recording each decision with the observation that would make me revisit it. The preconditions are social too: emergence needs continuous refactoring, a shared design bar, and it does not compose across ownership boundaries.

go deeper

for a junior

Take away the headline: some decisions are cheap to change later and some are not, and the expensive ones — what you store, who you talk to — are not left to sort themselves out.

for a middle

Be able to give examples on both sides and say why: a class split is a refactoring, while a stored data shape or a boundary between processes needs a migration and cannot be reshaped in one commit.

for a senior

Show the test you apply in practice — cost of reversal and whether a green commit series can reach it — and describe an occasion when you decided something up front because emergence could not have got there.

for a principal

Own both halves. Argue for the thinnest skeleton you can defend, record each decision as a hypothesis with a revisit trigger, and name the organisational preconditions — continuous refactoring, a shared bar, single ownership — without which the advice does not hold.

### The framing that answers this well Emergent design is not a claim that every decision is equally cheap to defer. It is a claim about one particular class of decision: **structure that a later restructuring can reach.** The right question to ask about any decision is therefore not "is it design?" but **"can the refactor step get to this later, and what does it cost if I am wrong?"** Two properties decide it: * **Reversibility.** What does undoing this cost once there is production data, other teams, and a running system? Class shapes and module internals cost hours. A persisted data shape costs a migration. A boundary between processes costs a project. A published contract costs other people's calendars. * **Reachability.** Can it be changed inside code you own, in a series of commits that each keep the suite green? If yes, let it emerge. If changing it requires coordinating with someone else's release, or rewriting stored history, no amount of refactoring discipline will produce it. ### What does not emerge In practice the short list is stable: * **The shape of persisted data and its history.** Emergence rewrites code; it does not rewrite what you already stored. * **Process and deployment boundaries.** Splitting one unit into two is a refactoring; splitting one service into two is a project, because the calls between them become failures. * **Contracts consumed by other teams or external clients.** You can refactor behind them; you cannot unilaterally reshape them. * **Cross-cutting decisions that will be threaded through hundreds of call sites.** The time source is the classic one. In a marketplace bidding engine, "whose clock decides bid order" is a choice that touches ordering, auto-extend, audit and expiry. Left to emerge, each area quietly makes its own choice, and at a 1,200-request-per-minute peak the disagreement shows up as bids stamped seconds in the future winning ties they did not win. Retrofitting one clock authority afterwards is not an extraction; it is an audit of every call site plus a data-quality problem in what was already recorded. * **Constraints imposed from outside the code** — regulatory retention, tenancy isolation, the security boundary. These are requirements, and they are cheaper as constraints than as discoveries. ### How I would actually run it Decide the smallest set of those deliberately, up front, as a thin skeleton — the boundaries, the stored shapes, the external contracts, the two or three cross-cutting authorities — and then leave everything inside them to emerge. The skeleton is intentionally thin: every item on it is a decision made with the least information you will ever have, so each additional item is a bet. Then treat each up-front decision as a hypothesis rather than a settlement. Write down the decision, the alternative you rejected, and the observation that would make you revisit it, and put a real trigger on it — a load level, a second consumer appearing, a third variation of a rule. Teams that skip this half end up defending a day-one decision for years because nobody remembers it was provisional. ### The organisational half, which is what makes it a lead's question Emergent design has preconditions that are social, not technical, and a principal-level answer names them: * It assumes **everyone refactors continuously.** Where the restructuring beat is the first thing dropped under delivery pressure, structure does not emerge — debt does. That has to be a stated policy with visible slack, not an aspiration. * It assumes a **shared design bar.** Emergence is a sequence of judgement calls; if five people hold five different bars, the result is five local optima that fight. Pairing, review, and regular design conversations are the mechanism, not decoration. * It **does not compose across teams.** Inside a team's own code it works well. Across an ownership boundary nobody can refactor both sides in one commit, so the boundary must be designed and the contract stated. This is the main reason "let it emerge" scales badly upward. * It is **weaker in unfamiliar territory.** In a legacy area with no suite, or a domain nobody on the team has modelled before, the first structures are guesses either way; there the honest move is a timeboxed spike to buy information, then decide. ### The trap to avoid on both sides One failure is treating everything as emergent, discovering at scale that the stored shape and the time authority were never decided, and paying for it in migrations. The opposite failure is concluding that because some decisions are irreversible, all of them must be settled up front — that is how you get an architecture document that specifies class names for code nobody has written. The skill is drawing the line in the right place and saying out loud why each item is on the short side.

  • Why does the source of time belong on the short list of up-front decisions?
    Because it is cross-cutting: ordering, expiry, audit and any windowed rule all consult it. Left to emerge, each area quietly picks its own answer, and the disagreement only appears under real traffic — a stamp seconds ahead of the receiving clock winning a tie it did not win. Retrofitting a single authority afterwards means auditing every call site and correcting data already recorded, which is exactly the kind of change a restructuring step cannot reach.
  • How do you stop the up-front skeleton from growing into a full design document?
    Apply the reachability test to each candidate and require an explicit reason it fails. Anything that can be changed in a green commit series inside code you own comes off the list by default. Keeping the list short is a discipline: every item is a bet made with the least information you will ever have, so the cost of a wrong item is paid for the life of the system.
  • What organisational preconditions does emergent design have, and what happens when they are missing?
    It assumes everyone refactors continuously and holds a broadly shared design bar, and it assumes the code being reshaped is under one team's ownership. Where the restructuring step is the first thing dropped under delivery pressure, structure does not emerge and debt does. Where five people hold five different bars, you get local optima that fight. Across an ownership boundary nobody can refactor both sides in one commit, so that boundary has to be designed and stated.
  • How do you treat an up-front decision that later looks wrong?
    As a hypothesis that has now been falsified, which is why it was recorded with its alternative and a revisit trigger. The response is a deliberate change with a migration plan, sized honestly — not a defence of the original choice because it was made early, and not a quiet workaround in each area that hits it. Teams that skip the recording step end up defending day-one decisions for years.

saying these in an interview costs you the question

  • Says everything can emerge, including the stored data shape
  • Designs the whole system up front because some decisions are irreversible
  • Treats an up-front decision as permanent and never revisits it
  • Ignores that a contract other teams consume cannot be reshaped unilaterally
  • Assumes emergence works on a team that does not refactor
  • Confuses splitting a unit with splitting a running process

context