Technical Diagrams
Most architecture diagrams are wrong. Not wrong when drawn — wrong six months later, because they were exported as a PNG from a tool only one person has access to, and updating them means reopening a file, rearranging boxes, re-exporting, and remembering to commit the result. Nobody does that, so the diagram drifts until it's actively misleading, and new engineers form a mental model of a system that no longer exists.
Diagrams-as-code solves it the same way docs-as-code solves stale prose. The diagram is a text file, lives next to the code, is reviewed in the pull request, and renders automatically. Anyone can edit it. Changes show up as a readable diff. And because Mermaid renders natively in GitHub, GitLab, Notion, and most documentation tooling, there's no build step to forget.
The other half of the problem is choosing what to draw. A single diagram trying to show services, data flow, deployment topology, and request sequencing shows none of them. The C4 model is the standard answer: separate diagrams at separate zoom levels, each with one audience and one question.
TL;DR
- Diagrams as text, in the repo, reviewed in PRs. A PNG export is a diagram that will go stale.
- Mermaid renders natively in GitHub, GitLab, and most docs tools — the lowest-friction default.
- D2 and PlantUML produce better layouts for complex diagrams, at the cost of a build step.
- The C4 model separates zoom levels: Context → Container → Component → Code.
- Sequence diagrams are the highest-value type for explaining a flow across services.
- One diagram, one question. Don't combine architecture, data flow, and deployment.
- Label the arrows. An unlabeled line between two boxes conveys almost nothing.
- Generate what you can — ER diagrams from a schema, dependency graphs from a build.
Quick Example
A sequence diagram in Mermaid — the type you'll write most often:
That diagram answers a question prose handles badly: what is synchronous, what is asynchronous, and where does the request return to the client? The -) arrows (async) versus ->> (sync) carry information that three paragraphs would struggle to convey.
Core Concepts
The C4 model
Four zoom levels, each for a different audience:
Levels 1 and 2 are the ones worth maintaining. Level 3 is useful for a genuinely complex service, and level 4 goes stale within a sprint and duplicates what the code already says.
The value of a context diagram is that it fits on one slide and answers "what is this system and what does it touch?" for a new engineer, an auditor, or an executive — three audiences that otherwise get three different explanations.
Choosing a diagram type
Sequence diagrams are underused relative to their value. Most confusion about a distributed system is about ordering, synchrony, and failure paths — exactly what a sequence diagram shows and what a box-and-arrow architecture diagram cannot.
Mermaid
The pragmatic default, because it renders in GitHub, GitLab, Notion, Obsidian, Docusaurus, and most other places without any tooling.
Mermaid's weakness is layout: it uses automatic layout with limited control, and diagrams past roughly fifteen nodes tend to produce crossing edges and awkward placement. When you're fighting the layout, that's usually a signal to split the diagram rather than to switch tools.
D2 and PlantUML
When Mermaid's layout isn't enough:
D2 has a better layout engine (ELK), cleaner syntax, and genuinely attractive output, at the cost of a rendering step in your build. PlantUML is older, extremely capable, and has the broadest diagram-type coverage including proper C4 support via a standard library — its syntax is less pleasant and its ecosystem is mature.
Both require a build step to produce images, which means one more thing that can be forgotten. For most teams, Mermaid's zero-setup rendering outweighs its layout limitations.
Generated diagrams
Anything derivable from a source of truth should be:
A generated ER diagram is always correct. A hand-drawn one is correct on the day it's drawn.
Best Practices
Store diagrams as text, next to the code
The whole argument in one line. Text diffs in review, anyone can edit, no proprietary tool, no export step, and the diagram changes in the same PR as the system it describes.
One diagram, one question
An architecture diagram that also tries to show request sequencing, deployment topology, and data ownership becomes a wall of boxes. Draw four diagrams, each answering one question, and link between them.
Label every arrow
An unlabeled arrow means "these are related somehow," which the reader already assumed. The protocol, direction, and synchrony are the information.
Distinguish synchronous from asynchronous
Solid lines for synchronous calls, dashed for asynchronous or event-driven. In a system with a queue in it, this is the single most important distinction on the diagram and the one most often omitted.
Keep architecture diagrams under about fifteen boxes
Past that, nobody can hold it in their head and the layout becomes unreadable regardless of tool. Split by bounded context, by team ownership, or by C4 level.
Include a legend when notation isn't obvious
Shapes, colors, and line styles that carry meaning need explaining. A diagram whose conventions are only in the author's head is a diagram that gets misread.
Date it, or better, make it unnecessary
A rendered diagram in a wiki should carry a "last updated" date so readers can calibrate their trust. A diagram in the repo, updated in the same PR as the code, doesn't need one — which is a good argument for the latter.
Render in the docs pipeline
Mermaid renders natively in most tooling. For D2 or PlantUML, render during the docs build and commit or publish the output, so a reader never sees raw diagram source. Check that rendering succeeds in CI — a syntax error that produces a blank diagram is easy to miss.
Common Mistakes
Screenshots of a whiteboard
Diagrams in a proprietary tool one person can open
The everything diagram
Unlabeled relationships
Diagrams that contradict the code
Hand-drawing what could be generated
FAQ
Mermaid, D2, or PlantUML?
Mermaid unless you have a specific reason otherwise — it renders natively in GitHub, GitLab, and most documentation platforms with zero setup, which removes the most common reason diagrams don't get made. D2 when layout quality matters and you're willing to add a build step; its output is noticeably more attractive for complex diagrams. PlantUML when you need diagram types the others lack or you're in an ecosystem that already uses it.
Are drawing tools like Excalidraw or Figma ever right?
For thinking and for one-off explanations, absolutely — sketching on a shared canvas during a design discussion is faster than writing syntax, and Excalidraw in particular exports an editable .excalidraw file that can live in the repo. What they're bad at is being the long-term source of truth for a diagram that must stay accurate, because updating requires opening the tool. A reasonable split: sketch in Excalidraw, formalize the ones worth keeping in Mermaid.
How do I keep diagrams up to date?
The same mechanisms as documentation: keep them in the repo so they change in the same PR, add "does this change a diagram?" to the review checklist, generate whatever can be generated, and delete diagrams that have stopped being maintained rather than leaving them to mislead. A stale diagram is worse than no diagram because readers trust it.
How much detail belongs in an architecture diagram?
Enough to answer the diagram's one question, and no more. A container diagram doesn't need internal class structure. A sequence diagram for the happy path doesn't need every error branch — draw a second one for failure handling if it matters. When you're adding a box because it exists rather than because it's relevant to the question, stop.
Should diagrams be in the code repo or a wiki?
The repository, with the docs site rendering them. That's what makes them reviewable alongside the code and keeps them in sync. A wiki is acceptable for diagrams that don't correspond to code — organizational structure, process flows, deployment environments — where there's no PR to attach the update to.
Can AI generate diagrams from a codebase?
It's reasonably good at producing a first-pass Mermaid diagram from source or from a description, and that's a genuine time saving for the initial draft. What it doesn't know is which relationships matter, what the system is supposed to look like versus what accreted, or where the boundaries a team actually cares about lie. Treat the output as a starting point to be edited down — the editing is where the diagram becomes useful.
Related Topics
- Technical Writing — The broader documentation practice
- Docs-as-Code — The workflow diagrams should follow
- Architecture Decision Records — Where a diagram supports a decision
- System Design — What the diagrams describe
- Microservices — Where C4 levels earn their keep
- Docusaurus — Rendering Mermaid in a docs site
- Distributed Tracing — Generating real interaction diagrams
- READMEs — Where a small architecture sketch belongs