Skip to main content

Documenting architecture

Describe a system's architecture with C4 diagrams, drawn in Mermaid and stored in the repository beside the code. Draw the first three levels as needed: context, containers, and components.

Why: a single "architecture diagram" usually mixes people, deployables, and classes, so it answers no question well. C4 gives each audience one zoom level, and diagrams kept as text are reviewed, versioned, and updated in the same pull request as the change they describe.

The four levels​

C4 describes a system at four zoom levels. Each level shows one kind of element and answers one question.

LevelShowsQuestion it answersDraw it
1. ContextThe system, its users, and the external systems it talks toWhat is this and who uses it?Always, for any system others need to understand
2. ContainerThe deployable or runnable parts: web app, API, database, queueWhat runs, and how do the parts communicate?Always, once there is more than one part
3. ComponentThe major building blocks inside one containerHow is one container organized?Only for a container that is hard to understand from its code layout
4. CodeClasses and functionsHow is this implemented?Do not draw it. The code, the IDE, and Clean Architecture already show it

A C4 "container" is a runnable unit such as an API or a database, not a Docker container, although they often coincide.

Rules for every diagram​

  • One level per diagram. Do not mix people, containers, and classes in one picture.
  • Name every element, give its type, and give its technology, for example API [Container: FastAPI on AWS Lambda]. A box labeled only Backend forces readers to guess.
  • Label every arrow with what flows and how: Reads and writes orders [SQL over TLS]. An unlabeled arrow hides the most useful information.
  • Keep the diagram readable on one screen. If it needs scrolling, split it by zooming into one element at the next level.
  • Show intent, not inventory. Leave out elements that do not help answer the level's question.

Drawing C4 in Mermaid​

Use Mermaid flowchart diagrams with C4 labels. Mermaid also has a native C4 syntax, but it is marked experimental and gives limited control over layout, so it is not used here. Mermaid is the handbook's diagram standard (writing rules), and flowcharts render the same as the other diagrams on this site.

Conventions:

  • Put the element type and technology on a second line with <br/>, and wrap labels in double quotes.
  • Draw the system boundary as a subgraph.
  • Write arrow labels as a verb plus protocol, in double quotes, and break a long label onto two lines with <br/>. Mermaid clips an arrow label wider than about 200 pixels.

Worked example​

The example is an illustrative app on the lean profile (Deployment profiles). Names are placeholders.

Level 1: context​

Level 2: containers​

Level 3: components of the API​

Draw this only for a container that needs it. Here it shows one feature's layers, matching Clean Architecture.

Where diagrams live​

  • Keep each project's diagrams in that project's repository, in Markdown next to the code, not in a separate tool that drifts. The handbook holds the standard; projects hold their own diagrams.
  • Exact file location in a project (for example docs/architecture.md): TBD.
  • Update the diagram in the same pull request as the change that makes it wrong. This follows the definition of done: docs that describe changed behavior are updated in the same pull request.

Diagrams and decisions​

A diagram shows what the system is; an ADR records why it is that way. Link them: name the ADR in a caption under the diagram when a structure comes from a decision, such as splitting out a service (Monolith or services). When a change alters a container or an external dependency, update the diagram and add an ADR if it is an architectural decision.

Common mistakes​

MistakeWhy it hurtsFix
Mixing levels in one diagramIt answers no audience's questionSplit by level
Unlabeled arrowsReaders cannot tell what flows or over which protocolLabel with a verb and the protocol
Technology missing from boxesReaders cannot tell what runs whereAdd the type and technology
Drawing level 4It repeats the code and goes stale quicklyLink to the code instead
A component diagram for every containerMaintenance cost with little valueDraw it only where the code layout is not enough
A diagram never updatedA wrong diagram is worse than noneChange it in the same pull request as the code
Treating the diagram as the decisionThe reason is lostRecord the reason in an ADR