The fifteen-item high-level design checklist
coreintermediateFifteen items, and the reason to hold them as a list is that a design is rarely wrong in the part you thought about — it is incomplete in the part nobody mentioned. Read as a gap-finder rather than a script, the list falls into five groups. What is being built: requirements, constraints, capacity. Who talks to it: clients, APIs. What it is made of: services, data stores, caches, queues. What it depends on and where it runs: external dependencies, deployment topology. And how it behaves in the world: observability, security, failure handling, scaling strategy. The last group is where reviews find the most, because those four are the items a design can omit while still looking complete — a diagram with every component and no answer for "how would we know this is broken" reads as finished and is not. External dependencies deserve a specific mention too, because they are the parts you cannot fix during an incident, and a design that has not named them has not named its real availability ceiling. Used properly, the list is run near the end, once there is a design to test, and each item gets one of three answers: here is how we handle it, we deliberately do not handle it because X, or we have not thought about it. The third answer is the reason the checklist exists, and writing it down beats discovering it later.
Think of it as
A pre-flight checklist. Its value is not that pilots forget how to fly — it is that a list catches the one item a competent, busy person skipped, and it catches it before departure rather than in the air. It is read aloud near the end, it is answered item by item, and "not checked" is a valid answer that stops the flight. Treating it as a script to recite from the start would be useless; treating it as a final gap-finder is why it works.
What we're doing: Run the behaviour group against a design that already looks finished.
- 8
- This is the most common observability gap in any design: monitoring is defined in terms of errors, and the failure that matters produces no error. A share that is created and never delivered is a successful request on every dashboard.
- 19
- Revocation is where signed-URL designs regularly break their own promise, because the URL is valid until it expires regardless of what the system later decides. Naming it here is cheaper than discovering it in a security review.
- 30
- A degraded mode is only available if it was designed, and the checklist is the moment it gets asked about. "Everything fails" is a legitimate answer if it is a decision — it is a gap when it is a discovery.
Why this works: Every one of these four gaps sits in the group a completed-looking diagram can omit entirely, which is why the behaviour group is where a checklist earns its keep. None of them are architecture mistakes; they are questions nobody was prompted to ask, and the prompt is the entire mechanism.
Running the checklist as an agenda from the start
Wrong
Better
What you see: A design that covers all fifteen items uniformly and commits to nothing, with the genuinely hard part of the problem given the same three minutes as the client list.
Why: A checklist tests a design; it cannot generate one. Used up front it dictates structure and spreads attention evenly, which is the opposite of what a design needs — and it also loses the property that makes it work, which is that the answers are checked against something real rather than imagined item by item.
- What is being built
- Requirements
- Constraints
- Capacity
- Who talks to it · what it is made of
- Clients
- APIs
- Services
- Data stores
- Cache
- Queues
- What it leans on
- External dependencies — the real availability ceiling
- Deployment topology
- How it behaves
- Observability
- Security
- Failure handling
- Scaling strategy
The fifteen items, grouped by the question each answers
The three permitted answers per item
Remember: Fifteen items in five groups: what is being built (requirements, constraints, capacity), who talks to it (clients, APIs), what it is made of (services, stores, cache, queues), what it leans on (external dependencies, deployment topology), and how it behaves (observability, security, failure handling, scaling). Run it near the end against a real design, give each item one of three answers — handled this way, deliberately not handled because X, or not yet considered — and make every "handled" specific enough that a reviewer could disagree with it. The behaviour group is where the finds are.
See also: what belongs in a high level design · moving between abstraction levels · the ten step sequence · mapping critical vs optional dependencies · symptom based alerting · defining degraded mode

