In this chapter
Why diagrams.
What they are. A diagram is a deliberately compressed representation of a system. It strips out detail to expose structure. The compression is the point: the diagram is useful because it is smaller than the thing it describes, and the smallness forces the author to choose what matters.
Why they matter. A team that cannot draw its own system at the right altitude does not understand the system. The drawing is the test. If the engineer asked to sketch the architecture produces something incoherent, or jumps directly to internal classes without first showing what the system talks to, the gap is in their model, not their drawing skill.
The trap. Most engineering diagrams are produced for ceremony rather than thought. A class diagram appears in a design document because design documents have class diagrams, not because the author needed to think through inheritance to make a decision. A flowchart appears because flowcharts are familiar, not because the question being answered was a question about flow. The result is decoration: technically correct drawings that don’t change anyone’s understanding because they weren’t produced as part of understanding anything.
The chapter below covers four kinds of diagram, each suited to a different altitude and a different question. None of them is universally right. The discipline is choosing the kind that matches the question you actually have, and refusing to default to whatever’s habitual.
The context diagram.
What it is. The highest-altitude view of your system. It shows the system as a single box, surrounded by the external entities it talks to, with labeled flows of information or material between the box and each entity. Internals are deliberately absent. The diagram answers one question: what is this system’s role in the world it sits in?
Why it’s the most undervalued diagram in engineering. Almost every confused conversation about a system is rooted in the participants having different mental models of what the system’s boundaries are, what crosses those boundaries, and what doesn’t. A context diagram resolves that — not by being clever, but by forcing the team to write down what entities exist, what data flows where, and what the system is and isn’t responsible for. The diagram becomes the single source of truth that disagreements get resolved against.
The discipline. If you find yourself talking about the system’s internals while explaining the context diagram, you’re drawing the wrong diagram. The context diagram is silent about how the system works. It speaks only about what the system is for and who else is in the picture.
How to read it. The Telemetry Processor is the system being designed. The four ellipses are external actors — entities the team does not own but must interact with. Each labeled arrow is a flow of information across the boundary, with a name short enough to be useful in a meeting. The diagram says nothing about how the Telemetry Processor works internally. That is a separate diagram, drawn for a separate question.
What this diagram catches that no other diagram does. The complete enumeration of the system’s external dependencies. If the team can’t name an external actor, they have no test path for it, no interface document for it, and no risk register entry for it. The context diagram is the cheapest way to surface those gaps before the project commits to an architecture that doesn’t accommodate them.
The C4 model: zoom in by levels.
What it is. A discipline (and an associated set of diagrams) for describing software architecture at four altitudes: System Context, Containers, Components, and Code. Each level is a zoom-in of the previous one, with the same conventions for shapes and labels at every altitude. The technique was developed by Simon Brown in the software world, but the underlying idea — that you describe a system at one altitude at a time, and zoom in deliberately — generalizes to any kind of engineering documentation.
Why it works. The mistake most engineers make when documenting an architecture is mixing altitudes — a diagram that has external actors, internal subsystems, and individual classes all on the same page. The result is unreadable: too much for the person trying to understand the boundary, not enough for the person trying to understand a class. C4 fixes this by insisting that each diagram has exactly one altitude, and by giving you a vocabulary for the four altitudes that matter most.
How to read it. Each level answers a different question for a different audience. Level 1 explains the system to anyone — including non-technical stakeholders. Level 2 shows the deployable units (services, databases, frontends, embedded controllers) and how they communicate. Level 3 zooms into one Level-2 container and shows its internal components. Level 4 is rare; most projects don’t need static class diagrams because the IDE shows you that. The discipline is to draw the levels you need and stop there.
The C4 mindset, even if you don’t use the formal notation. Pick an altitude before you draw. State the altitude and the audience explicitly. Don’t mix altitudes on one diagram. When the conversation about the diagram drifts into a different altitude (“but how does the cache work” while looking at the L1 context), recognize that’s a different diagram and either draw it now or note it for later. The technique is recoverable from this single rule: one diagram, one altitude, one audience.
Flowcharts.
What they are. A diagram of a process — a sequence of steps and decisions, with arrows showing how control flows from one step to the next. The shapes have conventions (rectangles for steps, diamonds for decisions, ovals for start/end) but the conventions matter less than the discipline of distinguishing “a thing happens” from “a choice gets made.”
When to reach for one. A flowchart is the right tool when the question is about order: what happens first, what depends on what, where the branches are. It is the wrong tool for everything else — structural questions, data questions, interface questions. Most flowcharts in engineering documents are answering questions that aren’t about flow, which is why they feel obligatory rather than illuminating.
How to read it. The diagram shows a poll loop: read the sensor, check whether the reading is valid, branch to either calibration-and-logging or invalid-marking, then back to the start. The thing the flowchart makes obvious that prose hides is the explicit invalid branch — the question “what happens when the reading is bad?” cannot be skipped, because the chart has a diamond and the diamond demands two outgoing arrows. That forced enumeration is the pedagogical value of the form.
What flowcharts cost you. They scale poorly. A thirty-step flowchart is unreadable, even if every step is correct. If your process has more than a handful of decisions, the answer is not a bigger flowchart — it’s a different kind of diagram (state machine, sequence diagram, or just structured prose).
UML, and the trap of the class diagram.
What UML is. The Unified Modeling Language is a family of diagram conventions for software systems. It includes structure diagrams (class, component, deployment), behavior diagrams (state machine, activity), and interaction diagrams (sequence, communication). Each kind answers a different question, and the family as a whole is more useful than any one member.
The trap. Most engineering teams that use UML use only the class diagram, and they reach for it without thinking about whether the question they have is a question about classes. The result is documents full of class diagrams that nobody reads, because the question the team actually has — “what happens when this command arrives?” or “how does this state machine evolve?” or “what runs on which box?” — isn’t a question about classes. The class diagram is the wrong tool.
The other UML diagrams that come up regularly:
- Sequence diagram. Shows a sequence of messages between actors over time. Reach for it when the question is “in what order does this happen?” especially across boundaries.
- State machine diagram. Shows the states a thing can be in and the events that move it between states. Reach for it when the question is “what behavior is legal in each mode?”
- Activity diagram. A flowchart on UML conventions, with parallelism and synchronization explicit. Reach for it when the question is “what work happens in parallel and where does it converge?”
- Deployment diagram. Shows what software runs on what hardware. Reach for it when the question is “where does each thing physically live?”
- Component diagram. Shows components and their connections. Useful but largely subsumed by C4 Levels 2 and 3.
The discipline. Before you draw a UML class diagram, ask: is the question I have a question about which classes exist, what they contain, and how they relate by inheritance and composition? If yes, the class diagram is the right tool. If the question is about timing, state, deployment, or process, choose the diagram that matches the question. The class diagram has earned its reputation because it’s overused, not because it’s bad.
The bad-API example.
One specific failure mode is worth a section because it shows up everywhere and is invisible to the team that’s causing it. An API gets defined — an interface, a function signature, a message schema — and the team building it skips the design step where a context-level question gets asked: what does the consumer need to know to use this correctly?
The classic example: a function that accepts latitude and longitude and is meant to be used in a space environment. That signature looks complete. It is incomplete, and the consumer has to find out the hard way. Latitude and longitude relative to what? The Earth-centered Earth-fixed frame, the inertial frame, the spacecraft body frame? At what epoch? In what units — degrees, radians, the WGS-84 datum, some other ellipsoid? The function’s shape doesn’t answer any of these. The team that wrote it knows the answers, because they wrote it. The team that has to call it doesn’t.
The fix in the latitude / longitude case is to make the frame and the units part of the type system or the parameter list. A function that takes position_eci_meters instead of latitude, longitude can’t be misused as easily, because the name carries the context the bare floats hid. A function that takes a Position struct with a frame field and a units field is even better, because the consumer cannot accidentally pass the wrong frame — the type system prevents it.
This generalizes. Every interface should encode enough context that a competent stranger reading just the signature can use it correctly. If understanding the interface requires reading the implementation, the interface has failed at its job.
Why this connects to context diagrams.
The bad-API failure is the same failure as the missing context diagram, applied at a different altitude. Both come from the team having a mental model that they didn’t externalize, and both lead to consumers who can’t use the system without becoming experts in its internals. The discipline is the same: name the entities, name the boundaries, name what crosses each boundary — and write it down where the consumer can see it.
A diagram, an API, and a piece of documentation are all answers to the question “how does someone outside this team use what we’re building?” If the answer is “by reading our internals,” the answer is wrong. The discipline of context diagrams, well-shaped APIs, and right-altitude documentation is the discipline of refusing to make the consumer pay for context the producer didn’t externalize.
Choosing the right tool.
The four kinds of diagram above each answer a different question. The matrix below maps the question you have to the kind of diagram that answers it. When the question doesn’t fit any row, the answer is usually that you don’t need a diagram — you need a written paragraph.
| Question | Best diagram | Why |
|---|---|---|
| What does this system talk to? | Context diagram | Forces enumeration of external dependencies. Hides internals on purpose. |
| How is this system organized at the architecture level? | C4 L2 (Containers) | One altitude, one audience. Avoids the everything-on-one-page failure. |
| How does one container work internally? | C4 L3 (Components) | Same conventions as L2, zoomed in. |
| What happens in what order during this scenario? | Sequence diagram | Time on one axis, actors on the other. Answers the “in what order” question directly. |
| What states can this thing be in? | State machine diagram | Forces enumeration of legal states and transitions. Catches missing transitions. |
| What does this process do, with branches? | Flowchart or activity diagram | Distinguishes “a step” from “a choice”. |
| What software runs on what hardware? | Deployment diagram | Maps logical components to physical machines. |
| What classes exist and how do they relate? | UML class diagram | Reach for it only when the question is actually about classes. Often it isn’t. |
Tools to draw with.
The drawing tool matters less than the discipline of choosing the right diagram. Among the options most engineers reach for:
- draw.io / diagrams.net. Free, browser-based, widely supported. The default for non-text diagrams in most teams.
- Mermaid. Text-based. Lives in markdown files, renders to SVG. The right choice when you want diagrams in source control alongside code, reviewable as diffs.
- PlantUML. Also text-based, more UML-native than Mermaid, with stronger support for sequence and state machine diagrams.
- Structurizr. Built specifically for C4. Worth knowing about if you’re using the C4 model formally.
- Pen and paper. Faster than any tool for the first draft. The diagram you sketch in five minutes on a whiteboard is more valuable than the polished one you’d produce in an hour, because you’ll be willing to throw it away when the model changes.