1.What belongs in a high-level design
A high-level design answers "what are the moving parts, and how does data get between them". Its vocabulary is components and services, the data stores each one owns, the queues and streams that connect them asynchronously, the network and trust boundaries they sit inside, and the major flows — the two or three paths that carry most of the system's traffic and value. The boundaries deserve particular attention, because a boundary is where the properties change: a call that crosses a process boundary can fail in ways an in-process call cannot, a call that crosses a trust boundary needs authentication and authorization, and a call that crosses a network boundary needs a timeout. Marking them is what makes the diagram say something rather than merely arrange things. What does not belong is anything about the inside of a box: class names, method signatures, schema columns, algorithms. Not because those are unimportant, but because a reader at this level is asking a different question, and mixing the two produces a diagram that is too detailed to see the shape and too incomplete to implement from. A good test is whether the design still reads correctly if one component's internals were replaced entirely — if it does, the level is right.
Key features
- The vocabulary is components and services, the data stores each owns, the queues and streams between them, boundaries, and the major flows
- Two or three major flows are enough — a high-level design that traces every path has stopped being high-level
- Mark network, process and trust boundaries explicitly, because that is where failure modes and security requirements change
- Distinguish synchronous calls from asynchronous ones, because that difference determines the system's failure behaviour
- Class names, method signatures, schema columns and algorithms belong one level down
- Test: if a component's internals were replaced entirely, the high-level design should still be correct
In a high-level design, and not
- Client
- leads to Edge / CDN
- Edge / CDN — trust boundary crossed here
- leads to API gateway
- API gateway
- leads to Orders service (sync)
- Orders service — owns the orders database
- leads to Orders database
- leads to Event stream (async)
- Orders database
- Event stream — asynchronous edge
- leads to Search indexer
- Search indexer — owns the search index
Command
A high-level design, written out
[browser] --https--> (edge/CDN)
|
== trust boundary ==
v
(api gateway) --sync--> (orders svc)
| owns
v
[orders db]
|
(orders svc) --async--> {events}
|
(search indexer)
| owns
v
[search index]
Major flows: 1) place an order 2) search ordersA high-level design names the components and services, the stores each one owns, the queues between them, the network and trust boundaries, and the two or three major flows — and marks which edges are synchronous. Boundaries matter most, because they are where failure modes and security requirements change. Nothing about the inside of a box belongs here: if a component's internals could be replaced entirely and the design still read correctly, the level is right.