The problem: one diagram, five audiences

A team inherits a whiteboard photo titled "architecture". It has boxes of different sizes, arrows with no labels, a cloud shape that might be a database, and a legend nobody remembers. The product owner cannot tell what the system does, a new developer cannot tell where to put code, and the operations engineer cannot tell what to monitor. The diagram tries to answer every question at once, so it answers none.

The C4 model fixes this by treating architecture diagrams like maps. A map of a country, a city and a street are different drawings of the same place, each with a different zoom level and audience. C4 defines four zoom levels: context, container, component and code. It is not a tool or a file format; it is a way of deciding what goes on which diagram. You can draw it in any tool, or in plain text.

The four levels

Level 1, system context. One box for your system, surrounded by the people and external systems it interacts with. No technology choices. The audience is everyone, including non-technical stakeholders. The question it answers: what is this system, who uses it and what does it depend on?

Level 2, containers. Here "container" does not mean Docker. It means a separately runnable or deployable unit: a Spring Boot service, a single-page application, a PostgreSQL database, a message broker, a batch job. Each box carries its technology and responsibility. The audience is developers, operations and architects. The question: what are the moving parts, how do they talk and where does data live?

Level 3, components. Zoom into one container and show its major building blocks: for a Spring Boot service, perhaps the REST controllers, an OrderService, a payment client and a repository layer. The audience is the developers working on that container. Draw this level only for containers whose structure is not obvious.

Level 4, code. Class or table diagrams. Almost always generated from code on demand and rarely worth maintaining by hand.

An example: a small booking system

Level 1 for an online booking platform:

+--------------+      books      +-----------------------+
| Customer     |---------------->|  Booking Platform     |
| [Person]     |                 |  [Software System]    |
+--------------+                 |  Lets customers book  |
                                 |  and pay for slots    |
+--------------+   manages       |                       |
| Venue Staff  |---------------->|                       |
| [Person]     |                 +-----------------------+
+--------------+                    |               |
                         card       v               v   emails
                         payments +---------+  +-----------+
                                  | Payment |  | Email     |
                                  | Provider|  | Service   |
                                  | [Ext.]  |  | [Ext.]    |
                                  +---------+  +-----------+

Level 2 zooms into the Booking Platform box:

 Customer          Venue Staff
    |                  |
    v HTTPS            v HTTPS
+--------------------------------+
| Web App [React SPA]            |
+--------------------------------+
            | JSON/HTTPS
            v
+--------------------------------+     +-------------------+
| Booking API                    |---->| Payment Provider  |
| [Spring Boot 3, Java 21]       |     | [External, REST]  |
| Validates, books, orchestrates |     +-------------------+
+--------------------------------+
   |                |
   | JDBC           | publishes BookingConfirmed
   v                v
+-----------+   +-----------+     +-----------------------+
| Database  |   | Broker    |---->| Notification Worker   |
| [Postgres]|   | [Kafka]   |     | [Spring Boot]         |
+-----------+   +-----------+     | Sends emails          |
                                  +-----------------------+

Notice what is present: every box has a type and technology in brackets, every arrow has a direction and a verb or protocol, and the system boundary is clear. Notice what is absent: no class names, no cloud-provider icons, no decorative colors that carry no meaning.

Notation tips that save readers time

  • Give every element a name, a type (Person, Software System, Container, Component) and a one-line responsibility.
  • Label every arrow with the intent ("submits order") and, at container level, the protocol ("JSON/HTTPS").
  • Prefer one-directional arrows that show who initiates the call. Bidirectional arrows hide the real dependency.
  • Include a legend if you use colors or shapes, and keep the same meaning across all diagrams.
  • Give every diagram a title that states its level and scope, for example "Container diagram for Booking Platform".
  • Keep diagrams to roughly a dozen elements. If you need more, split by zooming in, not by shrinking the font.
  • Avoid mixing levels. A database table next to a person on the same diagram is a sign that the level has drifted.

Choosing the audience first

Before drawing, write one sentence: "This diagram helps [who] decide [what]." A context diagram helps a sponsor see which external parties the system depends on. A container diagram helps a new developer find where a feature belongs and helps an operator find what must be monitored. A component diagram helps the team that owns one container plan a refactoring. If you cannot finish the sentence, the diagram is not needed yet. This habit also tells you when to stop adding detail.

Keeping diagrams current

Diagrams rot when they live outside the place where changes happen. Three practices help.

First, store them as text next to the code, in the same repository, so a Pull Request that changes a container also changes its diagram. Text-based formats review well and show clean diffs.

Second, treat diagram changes as part of the definition of done for structural changes: a new service, a new datastore, a new external integration. Day-to-day code changes do not need diagram updates, which is exactly why you should stop at the container level.

Third, link diagrams to Architecture Decision Records. The diagram shows what exists; the ADR explains why. Together they answer most onboarding questions.

Common mistakes

  1. Using a container as a Docker image. A container in C4 is a deployable unit with its own process or data store, regardless of how it is packaged.
  2. Drawing everything at once. A diagram that shows users, services, classes and servers is a collage, not a view.
  3. Unlabelled arrows. "Calls" is not information. "Reads prices over REST" is.
  4. Showing infrastructure details at the wrong level. Load balancers, subnets and replicas belong in a deployment diagram, which is a separate supplementary view.
  5. Maintaining level 4 by hand. It goes out of date within days; generate it or skip it.
  6. No audience. If you cannot say who the diagram is for, you cannot decide what to leave out.

Supplementary views

The four levels are the base map, but they do not answer every question. Add a sequence or dynamic diagram to show behavior over time, and a deployment diagram to show where servers and environments sit. These extra views follow the same rules: a clear title, an audience and labelled arrows. Draw them only for flows that actually raise questions, such as payment or refund.

Trade-offs and when not to bother

C4 gives a shared vocabulary, but it does not describe behavior over time, so a sequence diagram is still better for a payment flow. It also does not capture non-functional requirements or deployment topology by itself. For a single-service prototype that one person owns, a context sketch and a README paragraph are enough. The cost of the model is discipline: someone must own the diagrams and decide when they are stale.

Checklist

  • Is there a context diagram a non-engineer can understand in a minute?
  • Does the container diagram show every deployable unit and data store?
  • Does every arrow have a direction and a label?
  • Is each diagram titled with its level and scope?
  • Do diagrams live in the repository and change through Pull Requests?
  • Is there a named owner and an agreed trigger for updating them?

Where to go next

Record the reasoning behind your structure in ADR writing. See how architects use diagrams as part of their daily work in the solution architect role, or follow the Solution Architect roadmap.