Architecture From Requirements
Need persistence → a database. A browser interface → a frontend. Logic the client must not control → a backend. Payment → an external provider. Result: Browser → Backend → Database, plus the provider. Every box has a requirement that put it there, and no box is there without one.
The situation, the reflex, and why it stalls
Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.
You have the requirements for the store and a blank page where the architecture goes. How do you derive the boxes from the requirements — and how do you tell a box that a requirement put there from one that a habit did?
The requirements are written: browse, cart, guest checkout, pay, confirm; never oversell; admin edits products. You open the diagram tool and your hand draws what it always draws — a gateway, three services, a cache, a queue, a database per service — before you have looked at the list.
Draw the architecture you have seen. Diagrams from talks and reference architectures all have the same shape, and reproducing it feels like competence: this is what a real system looks like, and the store will be a real system. Deriving boxes from a requirements list feels naive by comparison.
The diagram has nine boxes and the requirements name reasons for four of them. The other five are answers to questions the store has not asked; each brings a deployment, a failure mode and an operational surface, and none brings a capability.
- The diagram has nine boxes and the requirements name reasons for four of them. The other five are answers to questions the store has not asked; each brings a deployment, a failure mode and an operational surface, and none brings a capability.
- Because the boxes came from a template, none of them can be defended in terms of the store. "Why a queue?" — "for order events." Which consumer? There is one, and it is the confirmation email. The answer is about the template, not the store.
- Requirements the store does have — never oversell, never charge twice — are not visible in the diagram at all, because templates draw infrastructure and those requirements live in the database and the payment handler. The diagram is about the wrong things.
- The first slice now has to cross nine boxes to display a product, and the walking skeleton takes a fortnight. Motion from the first day; the store still does not run.
The move
Precisely enough to apply it to a problem you have never seen — not a slogan.
- Derive each component from a requirement, and write the requirement beside the box. "Products and orders must survive a restart" → a database. "Customers use a browser" → a frontend. "The price and the stock check must not be under the customer's control" → a backend that owns the logic. "We do not handle cards" → an external payment provider. That is four boxes, and each can be defended by pointing at the sentence that produced it (What Must Persist, Where Does My System End?).
- For every box you are tempted to add beyond those, ask which requirement it serves. If the answer names a requirement that exists — an actual sentence in the list — the box stays. If it names a requirement that might exist later, the box waits, and the requirement goes on the assumption register so its arrival is noticed (When Assumptions Change).
- Let the non-functional requirements shape the boxes rather than add them. "Never oversell" shapes the database (a constraint, a conditional update) and the backend (the check lives there); it does not add a box. "Never charge twice" shapes the payment handler (idempotency); it adds no box either. Most hard requirements are shapes, not components.
- Accept the resulting diagram even when it looks small. Browser → Backend → Database, with a provider off to the side, is the architecture for these requirements. It is not a beginner's architecture; it is the derived one, and it will grow exactly when a requirement or a measurement asks it to (Add Complexity Only When Required).
Requirement → component
The matrix is the derivation. The left column is the sentences; the right columns say what each one produces. Notice how many rows say "shapes" rather than "adds": the requirements people worry about most — oversell, double charge — change the inside of a box and add nothing to the diagram.
| Requirement | Adds | Shapes | Where it lives |
|---|---|---|---|
| Products and orders survive a restart | Database | — | Product, Order, OrderItem, Payment tables |
| Customers browse and buy in a browser | Frontend | — | Pages for catalog, cart, checkout, confirmation |
| Price, total and stock check must not be under the customer's control | Backend | — | Checkout logic server-side; the client sends intent, not totals |
| We do not handle card details | Payment provider (external) | Backend: a confirmation handler | Provider is authoritative for "paid"; our handler records it |
| Never sell more than exists | — | Database: a constraint and a conditional decrement | The stock row |
| Never charge a customer twice | — | Backend: an idempotency key per checkout attempt | The payment handler |
| Customers get a confirmation | Email sender (external) | Backend: a pending-email record | A table and a scheduled send; a queue only if a requirement asks |
The derived diagram
This is what the matrix draws. Three components we own, two we do not. The notes on the boxes are the shaping requirements, which a template diagram never shows and which are the parts of the store most likely to be wrong.
What the derivation leaves unknown
A derived architecture is honest about what it has not settled. The board below is the store's after the derivation: the known side is the diagram; the unknown side is every place where a requirement might still arrive and add a box — each written as a question with the experiment that would answer it, so the pending list is a research plan and not a wish list.
- ✓Three components we own; two external systems that can fail without us.
- ✓Oversell and double-charge are shapes inside the database and the backend, not components.
- ✓The email is one consumer; a pending-email table and a scheduled send meet the requirement.
- ~One warehouse and one currency in V1 — on the register, so the two-warehouse sentence is noticed when it comes.
- ~Read traffic is small enough for the database to serve product pages directly; unverified until measured.
? Will the database cope?
becomes Under a burst of product-page reads of the size the newsletter can produce, what is the slowest component, and is it the product query?
experiment Generate the burst against staging; read the query timings; add an index if that is what is named.
? Do we need a queue for email?
becomes Does any requirement need the email to be sent outside the checkout request, and if the sender is down, what must happen to the order?
experiment Stub the sender to fail and walk one checkout: the order must still be created; the email must be retried later from the pending table.
? Realtime stock?
becomes Is there a requirement for a customer to see stock change without refreshing, or is a fresh read at checkout enough?
experiment Ask the founder; then confirm that the conditional decrement at checkout already prevents oversell without live stock.
None of the unknowns adds a box today. Each names the requirement or measurement that would, which is what makes the derived diagram stable rather than merely small.
How to do it
Most important first.
- Take the requirements list and, for each sentence, write the component it implies, if any. Most sentences imply a shape inside an existing component rather than a new one.
- Draw only the components that have at least one sentence beside them. Then draw the external systems the sentences name — payment, email — as boxes outside the boundary.
- For each box you wanted to draw and could not justify, write it in a list titled "pending a requirement" with the requirement that would justify it. The list is allowed; the diagram is not the place for it.
- Ask of the finished diagram: what is the first slice, and how many boxes does it cross? If the answer is more than the derived diagram has, something was added.
- Write the constraints that shape components — never oversell, never double-charge — onto the diagram as notes on the box they shape, so the diagram shows the requirements and not just the plumbing (What Must Never Break).
Worked on a concrete problem
The move has to produce something. This is what it produced.
- The store, derived. "Products and orders survive a restart" → database. "Customers browse and buy in a browser" → frontend. "Price, total and stock check are computed where the customer cannot alter them" → backend. "We do not touch card details" → payment provider, outside. "Customers receive a confirmation" → an email sender, outside. Result: Browser → Backend → Database; Backend → Payment Provider; Backend → Email. Five things, three of them ours.
- The template boxes, audited. Gateway: there is one backend; nothing to route between. Three services: catalog, cart and checkout share the product and order tables and the same deployment cadence; splitting them adds three deployments and a network hop inside the checkout path with no requirement served. Cache: no measured read load. Queue: one consumer — the email — and it can be a table of pending emails and a scheduled job if it must be asynchronous at all (Request or Background?). Each goes on the pending list with the requirement that would bring it back.
- The chat app, derived, to show a different result. "Messages appear without refresh" is a requirement, and it puts a persistent connection between browser and backend into the diagram — a box, or at least an edge of a different kind. "Read state on every device" shapes the data model. The chat app's derived architecture is one component larger than the store's, because one of its requirements asked for it.
- The requirement that arrived later. In month three the founder adds "orders ship from two warehouses, and stock is per warehouse". That sentence reshapes the database and the stock check; it still adds no component. It was on the assumption register as "one warehouse in V1", so its arrival was noticed and the reshaping was a planned loop, not a surprise.
How you know it worked
What now exists that did not before, and what question you can now ask.
- Every box on the diagram has a requirement written beside it, and the requirement is a sentence from the list rather than a category from a template.
- The non-functional requirements appear on the diagram as shapes — constraints, idempotency — on the boxes they affect.
- A "pending a requirement" list exists, and the boxes on it each name the requirement that would promote them.
- The first slice crosses the whole diagram in an afternoon.
The questions you can now ask
The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.
- ?For each requirement, which component does it imply — or does it shape one that already exists?
- ?For each box on my diagram, which sentence in the requirements put it there?
- ?Which of my requirements are shapes inside components — constraints, idempotency — rather than components at all?
- ?What requirement would have to arrive for each box on the pending list to be justified, and how would I notice it arriving?
What can go wrong
- Derivation taken as minimalism: a requirement that genuinely asks for a component is refused because small is good. "Messages appear without refresh" asks for a persistent connection; deriving an architecture without one is not deriving, it is ignoring a sentence.
- Requirements invented to justify boxes. "Scale" is written into the list as a requirement so the cache can stay. A requirement has a source — a person, a measurement, a contract — and one that has only a diagram to point at is a box in disguise.
- The pending list treated as a roadmap. Boxes on it are waiting for a requirement, not for a date; a queue that is scheduled for month four because that is when the pending list was reviewed has still not been asked for.
- The derivation done once and never again. Requirements change; the two-warehouse sentence reshaped the database. The diagram is re-derived when the list changes, and the assumption register is how the change is noticed.
- The derived diagram looks small, and to a reviewer expecting the template it can look inexperienced. The defence is the requirement beside each box, and it has to be made out loud.
- A derived architecture will change when the requirements do, and each change is visible rework. The template architecture absorbs some changes silently — at the cost of having paid for them whether or not they came.
- Deriving takes the requirements list seriously, and a list that is wrong produces a wrong architecture faithfully. The move depends on the requirements work before it.
- "Architecture from requirements means the simplest possible architecture." It means the architecture the requirements ask for, which for the chat app includes a persistent connection and for a payments company includes far more. Simple is the usual result for a store; it is not the rule.
- "Never draw a box without a requirement" forbids exploring. Draw as many as you like on the pending list; the rule is about what enters the design.
- "The external provider is not my architecture." The provider is a box you do not own and that can fail without you; leaving it off the diagram is how "what if payment is down?" never gets asked (External Systems Fail).
Where this applies
Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.
- GENERALEvery component in any system can be asked which requirement put it there; the answer differs by domain, but the question and the pending list do not.
- DOMAIN-SPECIFICThe derived store is three boxes because a store's requirements are simple. A payments processor whose requirements include audit, isolation of card data and regulatory reporting derives many more, and each can still point to a sentence; a regulated domain has more sentences.
- STAGE-SPECIFICOn a greenfield store the derivation starts from a blank page; in an existing system the boxes exist and the move inverts — for each box already running, which requirement keeps it there, and which could be removed?
- ILLUSTRATIVEThe nine-box template, the two-warehouse sentence in month three and the email consumer are invented to show the derivation; no real architecture or project is described.
Where the depth lives
This domain asks the question and hands the answer off by name.
- — The Architecture Evolution lab at /thinking/grow starts from exactly this diagram — single server and database — and adds boxes only when a reading justifies them.