The C4 Model
By the end of this module you will be able to:
- Name the four levels of the C4 model and the question each level answers
- Identify what belongs in a Container diagram versus a diagram
- Apply C4 notation conventions: box labels, technology annotations, and relationship arrows
- Decide when to use C4 instead of UML for a given documentation scenario
With the learning outcomes established, this module begins by examining the four levels in depth.
7.1 The four levels
The C4 model defines four hierarchical diagram levels. Each level zooms into the previous, with increasing detail. You do not need to produce all four: most teams only need Levels 1 and 2 to communicate architecture effectively.
Level 1: System Context. The highest-level view. Shows the software system as a single box in the centre, surrounded by the users who interact with it and the external systems it depends on. The audience is business stakeholders and non-technical readers. Every element is labelled with its name and a brief description. No technology choices appear at this level.
Level 2: Container. Zooms into the system boundary. A "container" in C4 terms is a separately deployable unit: a web application, an API, a database, a mobile app, a message queue. Each container shows its technology choice (React, Spring Boot, PostgreSQL). Arrows between containers show protocols and data exchanged (REST, , AMQP). The audience is technical team members and architects.
Level 3: Component. Zooms into a single container. Shows the logical building blocks inside it: controllers, services, repositories, domain objects. The audience is developers implementing or maintaining that specific container. Producing this for every container in a large system is unnecessary and expensive to maintain.
Level 4: Code. UML (Unified Modelling Language) class diagrams or entity-relationship diagrams for specific components. Optional, and rarely worth maintaining: modern IDEs generate class-level views on demand. Use Level 4 only for particularly complex or non-obvious designs.
C4 model: four nested levels, each answering a different question
Each row pairs a level with the question it answers and the audience that asks it, and each card below holds the elements that level absorbs, so a diagram drawn at the wrong level answers a question nobody brought.
Pick the level that matches the audience; most diagram failures are wrong level, not wrong notation. Source: Brown, c4model.com.
With an understanding of the four levels in place, the discussion can now turn to level 2: the container diagram, which builds directly on these foundations.
7.2 Level 1: the System Context diagram
The System Context diagram answers the question: "What does this system do and who interacts with it?" It deliberately omits all technical detail. The goal is to place the system in its environment so that a non-technical stakeholder can read it without training.
C4 notation for Level 1 uses three element types. A person is a human user (drawn as a box labelled with their role: "Customer", "Support Agent"). A software system is the system being documented (the box in the centre). An external system is any system outside the boundary: a payment gateway, a government identity service, an email provider. Dashed borders distinguish external systems from the one being documented.
Relationships are labelled with their purpose: "Uses (HTTPS)", "Sends notifications to", "Queries customer data from". The label describes the intent of the relationship, not just its technical mechanism. Arrows point in the direction of the dependency: if System A calls System B, the arrow goes from A to B.
With an understanding of level 1: the system context diagram in place, the discussion can now turn to level 2: the container diagram, which builds directly on these foundations.
7.3 Level 2: the Container diagram
The Container diagram answers: "What are the deployment units and how do they communicate?" A container is anything that must be separately started, stopped, scaled, or deployed. This is the level where technology choices first appear. Each container box includes: a name, a type (Web Application, REST API, Relational Database), and the technology used ("[Java / Spring Boot]", "[PostgreSQL 16]").
Containers within the system boundary are drawn with solid lines. External systems that the containers interact with are shown outside the boundary with dashed borders, mirroring Level 1. The audience for this diagram is the whole engineering team: it shows enough detail to understand deployment responsibilities without requiring knowledge of internal implementation.
The Container diagram is the most practically useful level for most teams. It is detailed enough to drive deployment decisions and technology conversations, and abstract enough to stay current as implementation details change. A well-maintained Level 2 diagram is the single most valuable architecture artefact most organisations produce.
With an understanding of level 2: the container diagram in place, the discussion can now turn to diagrams as code with structurizr, which builds directly on these foundations.
7.4 Diagrams as code with Structurizr
Architecture diagrams stored as images drift from the codebase. Structurizr DSL (Domain-Specific Language) allows C4 diagrams to be written as text files, version-controlled alongside code, and reviewed in pull requests. The CLI exports diagrams to PNG, SVG, or the Structurizr web application.
With an understanding of diagrams as code with structurizr in place, the discussion can now turn to c4 notation conventions, which builds directly on these foundations.
7.5 C4 notation conventions
C4 imposes minimal notation requirements. The key conventions are consistent labelling, not a specific graphical style. Every element should have a name (what is it called?), a type (what kind of thing is it?), and a brief description (what does it do?). Every relationship should have a label describing the intent and, at the Container level, the technology or protocol used.
Four element types appear across all levels. Person: a human user. Software System: an externally visible system. Container: a deployable unit within a Software System. Component: a logical building block within a Container.
External systems and external people are visually distinguished from internal elements, typically by colour or a dashed border. Making them visually distinct draws attention to the boundaries where integration risk exists: external systems are outside the team's control and can change without notice.
Common misconception
“C4 replaces UML.”
C4 covers architectural overview at four levels of abstraction. UML (Unified Modelling Language) excels at detailed design: sequence diagrams showing message order, state machines, activity diagrams, and class diagrams at the code level. They are complementary. Use C4 Levels 1 to 3 to communicate structural architecture, and UML sequence diagrams where interaction order is the most important thing to convey.
With an understanding of c4 notation conventions in place, the discussion can now turn to c4 vs uml: when to use which, which builds directly on these foundations.
7.6 C4 vs UML: when to use which
C4 and UML serve different communication needs. C4 is optimised for communicating structural architecture to a mixed audience: which systems exist, how they are deployed, and how they relate. Its constraint is abstraction: C4 does not express time-sequenced interactions, state transitions, or algorithm flows.
UML fills those gaps. A sequence diagram showing the exact order of messages between components during an authentication flow is the right tool for that conversation. A state diagram showing the lifecycle of an order (pending, paid, dispatched, delivered, refunded) communicates something that no C4 diagram can.
A practical decision rule: use C4 when the audience question is "what is this system made of and how do the parts relate?". Use UML when the question is "what happens when X occurs, in what order, and what are the possible states?". Most teams need both.
Pick the C4 level by the audience and the question they brought
The level is fixed by who is in the room, not by how much detail the author can draw: every row reads audience, then the question that audience brings, then the level that answers that question.
The diagram fails when it answers a question the audience never asked; the level follows the audience. Source: Brown, c4model.com; Procida, Diátaxis Framework, 2017.
Whichever notation a team picks, the diagram has to be kept current, and that is the harder half. A diagram that described the system accurately eighteen months ago is worse than no diagram at all, because it produces confident wrong decisions rather than admitted ignorance. Teams whose diagrams stay useful treat them as generated outputs rather than hand-drawn documents: written in a text DSL, kept in version control beside the code, reviewed in pull requests and rendered by the pipeline. If a diagram cannot be regenerated by a build, assume it is already out of date.
Common misconception
“All 4 C4 levels are always needed.”
Most teams only produce Levels 1 and 2. Level 3 (Component) is appropriate for complex containers where developers need to understand internal structure before making changes. Level 4 (Code) is almost never maintained manually: IDEs generate code-level views on demand. Producing all four levels for every service creates maintenance overhead that usually exceeds the value of the diagrams.
A team is drawing a Container diagram for an online banking system. One engineer objects that the PostgreSQL database should be left off it, on the grounds that the database is not run in Docker. Judged against the definition this module gives, who is right?
A System Context diagram prepared for business stakeholders labels the central system box [Java / Spring Boot]. What do the notation conventions in this module say about that label?
A team needs to document exactly what happens when a customer signs in: which service is called first, what it returns, and what the system does when the token has expired. Following the decision rule this module gives, which diagram fits that conversation?
Core distinctions
- The four C4 levels are System Context (Level 1), Container (Level 2), Component (Level 3), and Code (Level 4). Each answers a different question for a different audience.
- Level 2 (Container) is the most practically valuable level for most teams: it shows deployable units, technology choices, and communication protocols without requiring deep system knowledge to read.
- Levels 3 and 4 are optional. Most teams only need Levels 1 and 2. Level 3 is useful for complex containers; Level 4 is almost never maintained manually.
- C4 notation requires each element to have a name, type, and brief description. Each relationship must be labelled with intent and, at the Container level, protocol.
- C4 and UML are complementary. Use C4 for structural questions. Use UML for time-ordered interactions, state transitions, and algorithm flows.
- Storing C4 diagrams as DSL files and generating them in CI keeps them current without manual maintenance.
Standards and sources cited in this module
Brown, S. The C4 model for visualising software architecture. c4model.com.
Notation, tooling, and examples for all four levels
The authoritative reference for the C4 model, maintained by its creator. The naming, definitions, and notation rules in Sections 7.1 to 7.5 are all drawn from this source.
Brown, S. (2018). Software Architecture for Developers, Volume 2. Leanpub.
Chapters covering the C4 model, diagrams as code, and Structurizr
The book-form reference for the C4 model with worked examples. The source for the diagrams-as-code tooling and the Structurizr DSL discussed in this module.
Structurizr DSL documentation. docs.structurizr.com.
Language reference and export formats
The reference for the DSL syntax shown in Terminal Simulation 1. Structurizr is the primary tool for writing C4 diagrams as code.
PlantUML C4 macros. github.com/plantuml-stdlib/C4-PlantUML.
Macro library for C4 Container and Component diagrams
The alternative tooling shown in Terminal Simulation 2. Widely used because PlantUML output renders natively in GitHub, Confluence, and most documentation platforms.
Fowler, M. UML Distilled. 3rd edition. Addison-Wesley, 2003.
Chapter 4: Sequence Diagrams; Chapter 10: State Machine Diagrams
The reference for UML diagram types discussed in Section 7.6. Establishes sequence diagrams and state diagrams as the right tools for time-ordered and state-transition questions that C4 does not answer.
What comes next: Diagrams show what a system is. Threat models show what could go wrong with it. Module 8 introduces security by design: the STRIDE threat model, , supply chain security, and the lesson of Log4Shell - that a security design failure in a logging library can compromise millions of systems.
Module 7 of 31 in Foundations