The C4 Model: A Practical Guide to Software Architecture Diagrams
Architecture discussions often start with boxes and arrows, then stall because nobody knows what the boxes represent. Are they teams, services, processes, or source-code modules?
The C4 model gives software teams a simple way to describe architecture at different levels of detail. This guide explains what it is, when it helps, and how to make a small example with a free tool.
What Is the C4 Model?
C4 is a way to draw software architecture using four levels: Context, Containers, Components, and Code. It was created by Simon Brown, a software architect and author, to make architecture diagrams easier to understand and communicate.
The levels move from the big picture toward implementation detail:
| Level | Question it answers | Monitoring-system example |
|---|---|---|
| Context | What is the system, who uses it, and what external systems does it depend on? | Technicians use a monitoring system that receives readings from sensors and sends alerts through an email service. |
| Container | What are the system’s main applications or data stores, and how do they communicate? | A sensor gateway sends data to a web application, which stores readings in a database. |
| Component | What are the main responsibilities inside one container? | The web application has an ingestion API, alert evaluator, and dashboard API. |
| Code | How is one component implemented? | Classes, interfaces, or other code-level structures that explain a specific design. |
In C4, a container is an application or data store that runs or holds data, such as a web app, service, or database. It does not mean only a Docker container.
The first three levels are useful for most teams. The code-level view is optional: use it when implementation structure needs explanation, not as a diagram of every class.
Why and When Use It?
Use C4 when you need to:
- Explain a system to developers, operators, security reviewers, or non-technical stakeholders.
- Make service boundaries, responsibilities, dependencies, and data flows visible.
- Discuss a proposed design before implementation or record an existing one.
- Keep diagrams consistent as readers move from overview to detail.
It is especially helpful during onboarding, design reviews, incident analysis, and changes that cross service or team boundaries. You do not need all four levels for every system. A context diagram and a container diagram may be enough.
C4 is a diagramming model, not a development process, a detailed specification, or a replacement for every other diagram. Use a sequence diagram for a time-ordered interaction, a deployment diagram for where software runs, or a data-flow diagram when that view answers the question better.
A Small Example
Imagine a building temperature-monitoring system:
Context
Technician -> Monitoring System -> Email Provider
Temperature Sensors -> Monitoring System
Containers inside Monitoring System
Sensor Gateway -> Web Application -> Readings Database
|
+-> Email Provider
Components inside Web Application
Ingestion API -> Alert Evaluator -> Notification Sender
|
+-> Dashboard API -> Readings Database
These sketches are intentionally simple. A useful diagram also labels each element with its responsibility and technology when that information helps the audience, and labels important relationships with what is exchanged. Avoid drawing every box just because the model has a level for it.
Create Diagrams with a Free Tool
Structurizr provides the open-source Structurizr Lite application and DSL for describing C4 architecture as text. Lite runs locally; it is a good option when you want editable diagrams alongside source code rather than manually arranged shapes.
- Install Docker, then create a folder containing a file named
workspace.dsl. - Put this minimal model in the file:
workspace "Temperature Monitoring" "Building temperature alerts" {
model {
technician = person "Technician" "Responds to temperature alerts."
email = softwareSystem "Email Provider" "Sends alert messages." {
tags "External"
}
monitoring = softwareSystem "Monitoring System" "Collects readings and reports unsafe temperatures." {
gateway = container "Sensor Gateway" "Receives sensor readings." "Embedded Linux"
web = container "Web Application" "Displays readings and evaluates alerts." "Web application"
database = container "Readings Database" "Stores measurements." "SQL database"
technician -> web "Views readings"
gateway -> web "Sends readings"
web -> database "Stores and reads measurements"
web -> email "Sends alerts"
}
}
views {
systemContext monitoring "Context" {
include *
autoLayout
}
container monitoring "Containers" {
include *
autoLayout
}
theme default
}
}
- Start Lite from that folder:
docker run --rm -p 8080:8080 -v "$PWD:/usr/local/structurizr" structurizr/lite
- Open
http://localhost:8080to view the generated context and container diagrams. Editworkspace.dslto change the model and refresh the page.
The DSL is plain text, so it can be reviewed in Git and updated with the software. Check the current Structurizr Lite documentation for Docker image and usage details. If you prefer a visual editor, diagrams.net is also free to use; choose clear labels and keep each diagram focused on one level.
A Practical Starting Point
Start with one context diagram: name the system, its users, and its external dependencies. Then draw a container view only if readers need to understand the system’s main applications and data stores. Add components or code only to answer a real question.
The goal is not to produce four diagrams. It is to help people understand the software, its boundaries, and the decisions that matter.