C4 model
Модель C4 Саймона Брауна: четыре уровня описания архитектуры — Context, Container, Component, Code. Нотации, что показывать на каждом уровне и примеры диаграмм на сквозном кейсе маркетплейса.
All examples in this article use the site's end-to-end case: a high-load marketplace. C4 is a convenient way to explain a system's architecture to different audiences, from business to developers, without losing detail.
What C4 is
C4 is a set of diagrams that describe a system at different levels of detail. The levels are nested like a map: first you see the country, then the city, then the street.
| Level | What it shows | Audience |
|---|---|---|
| C1 — Context | The system in its environment: users + external systems | Business, managers, new hires |
| C2 — Container | Which containers (services, databases, queues) the system consists of | Architects, developers |
| C3 — Component | The internal components of a single container | Developers of that particular service |
| C4 — Code | Detail at the code level (classes, interfaces) | Optional, usually generated from code |
The core idea: the same notations at every level. You move from the general to the specific without losing context.
Why it's convenient for system design
- A single standard for diagrams — in a review or a design discussion you don't have to explain what each arrow means.
- Simple evolution: first Context → then Container → and if needed, Component.
- Easier to discuss boundaries of responsibility and integrations — each diagram answers its own set of questions.
Which level you need in system design
Required:
- Context (C1)
- Container (C2)
Recommended:
- Component (C3) — if a service has complex internal logic and you need to show its structure
Optional:
- Code (C4) — usually overkill. It's better to document code with the code itself.
The Context level (C1)
A context diagram is a good fit for business users who don't need to dive into technical nuances.
The diagram's goals — to answer the questions:
- Which users use the system being documented?
- Which systems does the documented system interact with?
- What are those interactions for?
Notations
| Element | What it represents |
|---|---|
| Person | A user of the documented system |
| System | The documented system — the highest level of abstraction, describing something that delivers value to users |
| System_Ext | An external system the documented system interacts with |
| Arrow | A relationship between elements. Points from the caller to the callee |
Example: a marketplace
This is a Context level diagram: you can see the system as a black box, its users, and external systems. No technologies are visible — that's intentional.
The Container level (C2)
A container diagram answers technical questions: what the system consists of and over which channels the containers communicate.
The diagram's goals:
- Which technologies does the system use?
- Which containers (services, databases, queues) does the system consist of?
- How do the containers interact with each other?
- How do the containers interact with external systems?
- How do users interact with the system?
Presentation guidelines
- Every container should have a technology and a zone of responsibility (for example: "Order Service: Spring Boot, order processing").
- Relationships are labeled: what the relationship does + the protocol (for example: "fetches the exchange rate, REST/JSON").
- External systems are always marked with
System_Ext. - Queues and databases are better shown separately (
ContainerQueue,ContainerDb).
Notations
| Element | What it represents |
|---|---|
| Container | A standalone part of the system, for example "Mobile App", "Order Service" |
| ContainerDb | A data store |
| ContainerQueue | A message broker or queue |
| System_Boundary | A group of containers that make up the documented system |
| Solid arrow | Synchronous interaction |
| Dashed arrow | Asynchronous interaction |
All notations from the Context diagram are also used.
Example: a marketplace
This diagram makes several things immediately clear:
- what — Customer API, the Catalog/Order/Payment/Inventory services, PostgreSQL, Elasticsearch, Kafka.
- on what — all services run on Spring Boot, a database per service.
- how they communicate — synchronous REST calls (solid arrows), asynchronous events through Kafka (dashed).
- what's outside — an external payment gateway and logistics.
The Component level (C3)
A component diagram zooms into one container and shows what internal parts it's made of and how a request flows through it. You draw it not for the whole system but for one non-trivial service — usually right in its README.
The diagram's goals:
- Which components the container consists of and what each is responsible for?
- How a request flows from the entry point (controller) to the store and outward?
- Where the boundaries between layers are — web, use case, domain, data access?
Notations
| Element | What it represents |
|---|---|
| Component | A logical component inside a container: a controller, a use case, a repository, a port |
| Container_Boundary | The boundary of the container we're zooming into |
| Arrows | As on the previous levels: solid — synchronous, dashed — asynchronous |
Example: looking inside the Order Service
We zoom into the Order Service container from the C2 diagram. Inside are components in the terms of the Use Case Pattern: the controller accepts the request, the use case describes the business step, the handler orchestrates it, and access to the outside world goes through ports (a repository, an event publisher).
Here you can see the request's path: POST /orders → controller → use case → handler, which reads and writes through the repository to PostgreSQL, synchronously calls the Payment Service, and asynchronously publishes the OrderCreated event to Kafka. The container's technologies are already known from level C2 — here what matters is the internal structure.
The Code level (C4)
The deepest level — down to classes and interfaces. In practice it's almost never drawn by hand: it goes stale quickly, and the best way to document code is the code itself. If a diagram is needed at all, it's usually generated from the sources (an IDE, plantUML). We show one component from C3 — CreateOrderHandler — just to indicate what the closest zoom looks like.
The takeaway on the Code level: occasionally useful (to explain a tricky spot), but as permanent documentation it loses to the code. So in system design it's almost always skipped.
When to use which level
- Explaining to business or a newcomer what the system does → C1 (Context).
- Designing the architecture, discussing it with the team → C2 (Container).
- Documenting a complex service from the inside → C3 (Component) — usually in that service's README.
- Showing specific classes → better to do a design review or link to the code.
Links
- A detailed description of the model — the official site by the author, Simon Brown: c4model.com.
- Structural patterns — patterns that show up on the C2 diagram.
- Case: a marketplace — C1/C2 for our system are there as well.