Module 3: Communicating Architecture

2. The C4 model: four levels of zoom

Overview

By the end of this lesson you'll know Simon Brown's C4 model, the tool that turns "you have to choose the diagram's zoom" from a good intention into a method with four named levels. The four Cs are Context, Container, Component, and Code —four ways of looking at the same system, from farther to closer—. Each one answers a different question for a different audience, exactly like the zoom levels of a map: the Context is the world map (what the system does and who it talks to), the Container is the city map (what deployable pieces it's made of), the Component is the neighborhood map (what's inside a piece), and the Code is the street map (how that component is written). C4's genius isn't that it's sophisticated —it's quite the opposite—: it's that with a single boxes-and-arrows notation and four zoom levels you cover almost the entire need to communicate an architecture, without memorizing the symbol soup of heavier notations almost no one remembers.

This matters because the problem C4 solves is real and old. Before C4, "making an architecture diagram" had no rules: everyone drew boxes of different sizes, with different meanings, mixing on the same sheet things from very different abstraction levels —a user, a database, a Java class, a message queue, all together—. The result was the diagram that "shows the system" and that no one knows how to read, because there's no agreement about what a box is or how far away you're looking. C4 brings order with a simple rule: decide first how far away you're looking —which of the four Cs— and only the boxes of that level go into that diagram. One diagram, one zoom. Completeness doesn't live in one sheet that shows everything; it lives in the set of diagrams, each clean at its level.

Connection with the module: in lesson 1 you saw, with Google Maps, that communicating an architecture is choosing the zoom according to who's looking. This lesson gives those zooms a name and a structure: the four levels of C4. It's the vocabulary you need before you can draw anything —you can't "choose the right level for the audience" (lesson 5) if you don't have the levels named—. In lessons 3 and 4 you'll draw each level in depth over Mercado: Context and Container (the two you'll use most) in lesson 3, Component and Code (and when to stop) in lesson 4. Here you build the ladder; in the next two you go down it, rung by rung.

Google Maps again: the zoom ladder

Return to Google Maps, because C4 is literally that. Imagine you start seeing the planet and keep pressing the zoom-in button, one level at a time, until you reach a house's door. Each press takes context away and gives you detail:

  • Zoom 1 — the world. You see continents and countries. You answer: "where is this country relative to the others?". You don't see a single street, and you don't miss them.
  • Zoom 2 — the city. You see avenues, districts, rivers, stations. You answer: "how do I move within this city?". You lost the view of the whole country, but you gained the main streets.
  • Zoom 3 — the neighborhood. You see the blocks, the buildings, the names of the small streets. You answer: "what's in this area and how does it connect inside?".
  • Zoom 4 — the street. You see the house number, the entrance, the tree on the corner. You answer: "exactly where is this address?".

Three things about this ladder are the whole C4. First: each zoom answers a question and serves someone different —the one planning an international trip uses the world, the courier uses the street—. Second: going up is moving away and going down is moving closer —more context up top, more detail down below, and you can't have both at the maximum at once—. Third, the most important: you don't mix zooms on one sheet. Google Maps never shows you the continents with the house numbers on top; it would be illegible. When you want to go down from the city to the neighborhood, the whole map changes level, coherent with itself. C4 asks exactly that discipline of your diagrams: choose a level, stay in it, and if you need another level, make another diagram.

The four Cs, one by one

Context (level 1 — the world map). Your system is a single box in the center, and around it are the people who use it and the external systems it talks to. It shows nothing of how it's built inside —no technologies, no pieces, no databases—. It answers: what does this system do, who uses it, and what other systems does it depend on? Its audience is the broadest: anyone, including the business, a VP, a customer, an investor. It's the only diagram you can put in front of someone non-technical and expect them to understand without explaining notation.

Container (level 2 — the city map). You zoom inside that single box and see the deployable pieces the system is made of: the web application, the mobile app, the backend API, the database, the search index. "Container" here doesn't mean Docker —it means something that runs and deploys separately: a process, an app, a database—. Each container shows its main technology (React, FastAPI, PostgreSQL). It answers: what pieces is the system made of, what's each one's responsibility, and how do they communicate? Its audience is technical: architects, developers, ops people. It's the most useful diagram of the set to orient someone who's going to work on the system.

Component (level 3 — the neighborhood map). You zoom inside one container —say the API— and see the components that make it up: groupings of code with a clear responsibility (the orders controller, the tax calculator, the payment gateway client). It answers: what's inside this piece and how do its parts collaborate? Its audience is narrow: the developers working on that container. You don't draw a Component for every container —only for the ones that are complex and worth it—.

Code (level 4 — the street map). You zoom inside one component and see the concrete classes, interfaces, and functions —a UML class diagram, for example—. It answers: how exactly is this component written? Its audience is the narrowest: the dev who's going to edit that code today. And here comes the surprise we'll see in lesson 4: this level is almost never drawn by hand, because the detail at that scale changes every day and a hand-made drawing ages in hours. When you really need it, a tool generates it from the real code, or you simply open the code. C4 includes it for completeness, but the architect's work lives almost always at levels 1 and 2.

Worked example: the C4 ladder, executed

Let's put the ladder in a table you can run, to fix which question each level answers and whom it serves. The following code doesn't draw diagrams: it prints the zoom ladder —the four C4 levels paired with their map analogy, the question they answer, and their audience—, so the mental model is clear before drawing in the next lessons.

# C4 as the zoom levels of a map: you choose the zoom according to what you're looking for.
# No one navigates a city with the world map, nor crosses the country with the street one.

zoom_ladder = [
    # (C4 level, map analogy, question it answers, main audience)
    ("Context",   "world map",   "What does the system do and who does it talk to?", "anyone, including the business"),
    ("Container", "city map",    "What deployable pieces is it made of?",            "technical people"),
    ("Component", "neighborhood map", "What's INSIDE a piece?",                       "devs of that piece"),
    ("Code",      "street map",  "How is that component written?",                   "the dev editing it today"),
]

print("The four C4 levels, as four zooms of one same map:")
print()
print(f"{'Zoom':<6}{'C4 level':<11}{'Map analogy':<19}Question it answers")
print("-" * 82)
for i, (level, mapa, pregunta, _aud) in enumerate(zoom_ladder, start=1):
    print(f"{i:<6}{level:<11}{mapa:<19}{pregunta}")
print()

print("Rule: each zoom answers ONE question for ONE audience.")
for i, (level, mapa, _pregunta, aud) in enumerate(zoom_ladder, start=1):
    print(f"  Zoom {i} ({level:<9}) -> {aud}")
print()
print("Going up a level = moving away (less detail, more context).")
print("Going down a level = moving closer (more detail, less context).")
print("The mistake isn't the ugly diagram: it's the wrong zoom for who's looking.")

What to expect. Running it:

The four C4 levels, as four zooms of one same map:

Zoom  C4 level   Map analogy        Question it answers
----------------------------------------------------------------------------------
1     Context    world map          What does the system do and who does it talk to?
2     Container  city map           What deployable pieces is it made of?
3     Component  neighborhood map   What's INSIDE a piece?
4     Code       street map         How is that component written?

Rule: each zoom answers ONE question for ONE audience.
  Zoom 1 (Context  ) -> anyone, including the business
  Zoom 2 (Container) -> technical people
  Zoom 3 (Component) -> devs of that piece
  Zoom 4 (Code     ) -> the dev editing it today

Going up a level = moving away (less detail, more context).
Going down a level = moving closer (more detail, less context).
The mistake isn't the ugly diagram: it's the wrong zoom for who's looking.

The table is the whole C4 in four rows. Notice the audience column: it goes from "anyone" at the top to "the dev editing it today" at the bottom. That's the model's key property —the audience narrows as you go down—. The Context is understood by half the world; the Code is looked at by a single person. And that's why the architect's communication work concentrates up top: the level 1 and 2 diagrams are seen by many people and are worth all the effort of doing them well; level 4 is seen by almost no one and is almost never worth drawing by hand. The last line is the module's moral: the diagram doesn't fail for being ugly, it fails for being at the wrong zoom for who's looking.

Now, the relationship between the four levels isn't a loose list: it's a nesting. Each level lives inside the previous one, like Russian dolls. Here's the ladder drawn:

+-------------------------------------------------------------+
|  LEVEL 1  CONTEXT  (the world map)                          |
|  Mercado as ONE box + its users + external systems          |
|                                                             |
|    +----------------------------------------------------+   |
|    |  LEVEL 2  CONTAINER  (the city map)                |   |
|    |  zoom INSIDE Mercado: web, api, db, search...      |   |
|    |                                                    |   |
|    |    +-------------------------------------------+   |   |
|    |    |  LEVEL 3  COMPONENT  (the neighborhood map)|  |   |
|    |    |  zoom INSIDE a container: e.g. the API    |   |   |
|    |    |                                           |   |   |
|    |    |    +---------------------------------+    |   |   |
|    |    |    |  LEVEL 4  CODE (the street map) |    |   |   |
|    |    |    |  zoom INSIDE a component         |   |   |   |
|    |    |    +---------------------------------+    |   |   |
|    |    +-------------------------------------------+   |   |
|    +----------------------------------------------------+   |
+-------------------------------------------------------------+

     Outside: less detail, more audience.
     Inside: more detail, less audience.

This nesting is the reason C4 is coherent: each diagram opens a box of the level above. The Container zooms into the Mercado box of the Context. The Component zooms into a box of the Container. The Code zooms into a box of the Component. You never skip two levels at once (from the Context to the Code) because you'd lose the route —just as Google Maps doesn't take you from the planet to the house number in a single jump—. And you never mix two levels on one sheet, because each diagram is one frame of this Russian doll, not two.

Why "one notation, four levels" wins

It's worth understanding what C4 is competing against, because that's where its value is. The historical alternative for diagramming software was UML (Unified Modeling Language), a standard with dozens of diagram types and hundreds of symbols: class diagrams, sequence, deployment, component, state, with precise notations for inheritance, composition, aggregation, multiplicity. UML is powerful and rigorous. It's also something almost no one remembers whole: most teams use a fraction, badly, and end up with diagrams only the one who drew them knows how to read —or worse, that everyone reads differently because not everyone remembers what the filled diamond means against the empty one—.

C4 makes the opposite bet: almost zero notation, almost all the value. Boxes, arrows, labels. A box is an element; an arrow is "uses" or "talks to", with a label saying how. No symbols to memorize. The discipline isn't in the notation but in the level of abstraction: the important question isn't "which symbol do I use?" but "how far away am I looking?". Anyone can learn that in five minutes, and —key for communicating— anyone can read it without training. A Mercado Context with five boxes and four arrows needs no legend: it's understood on its own. That legibility-without-training is exactly what's needed when your audience includes a VP who never saw an architecture diagram in their life.

This doesn't mean UML is "wrong" or that there's no place for richer notations —a UML sequence diagram is unbeatable for showing a message protocol step by step—. It means that for the task of communicating the shape of a system to different audiences, C4's simplicity is a virtue, not a lack. C4 and notations like UML aren't rivals: C4 gives you the zoom map to orient, and if at some point you need to detail a protocol, you use the specific notation within the right level. But the skeleton of your communication —what decides what to show to whom— is the four Cs.

Beyond the four Cs: the supplementary diagrams

The four Cs —Context, Container, Component, Code— are C4's skeleton, and with them you cover almost everything. But it's worth knowing that the model also offers a few supplementary diagrams, optional, for questions the four Cs don't answer well. You don't have to memorize them; it's enough to know they exist for when the need appears:

  • The System Landscape is a "Context of contexts": instead of a single system in the center, it shows several of the company's systems and how they relate to each other. It's useful when the question isn't "what is Mercado like?" but "how does Mercado fit into the map of all the organization's systems?" —a view even higher than the Context—.
  • The Dynamic diagram shows a sequence: how the elements collaborate to complete a concrete case, numbered step by step ("1. the web calls the API; 2. the API validates the stock; 3. the API charges..."). It answers "how does this operation flow?", which the four Cs —static— don't capture.
  • The Deployment diagram shows where each container runs in the real infrastructure: what runs on which server, container, or cloud. It answers the ops question —"where does this live deployed?"— that the logical Container doesn't address.

The reason for mentioning them and moving on is the module's same discipline: don't use them by default. Most systems communicate well with Context + Container + (sometimes) Component, and adding landscape, dynamic, or deployment "so it's complete" is falling back into the museum. They're there for when a specific question calls for them —a complex operation that has to be explained step by step, a deployment that confuses ops— and not before. The skeleton is still the four Cs; these are reserve tools.

Common mistakes

Believing "Container" means Docker (of the false friend). What happens: someone hears "Container" in C4 and assumes it refers to Docker or Kubernetes containers, and then their Container diagram only makes sense if the system uses containers. Why it happens: the word stole the meaning in the industry. How to spot it: if your level 2 diagram empties out when the system doesn't use Docker, you misunderstood the term. How to fix it: in C4, a container is anything that runs and deploys separately —a process, a desktop app, a database, a serverless function, a browser running your SPA—. A PostgreSQL database is a container even if there's not a single Docker in the project. Level 2 asks "what deployable pieces are there?", not "what Docker containers are there?".

Skipping levels or mixing them (of impatience). What happens: the diagram goes from the whole system (Context) directly to showing classes (Code) on the same sheet, or mixes containers with internal components. Why it happens: out of haste or wanting to "show everything at once". How to spot it: if in your diagram a box representing "the complete system" coexists with another representing "a class", you jumped from zoom 1 to zoom 4 with no intermediate scale. How to fix it: respect the nesting —each diagram opens one box of the level above—; if you need to show the interior of a piece, make a new diagram of that level, don't stack it on the previous one. Lesson 7's hard rule: one diagram, one level.

Wanting a Component (or Code) diagram for every piece (of exhaustiveness). What happens: the team decides to "document well" and makes a Component of each of the five containers, and then a Code of each component, and ends up with thirty diagrams no one maintains. Why it happens: completeness is confused with quality —"if we document every level of everything, it'll be well documented"—. How to spot it: if you have more diagrams than someone reviews or updates, you're maintaining a museum, not communication. How to fix it: Context and Container almost always; Component only in the complex containers that warrant it; Code almost never by hand. The zoom rule (lesson 4): you go down a level only where the detail helps a real person work.

Exercises

Exercise 1 — Place the element at its level. For each of these Mercado elements, say at which C4 level it would appear as a box: (a) "a customer who buys"; (b) "the search index (Elasticsearch)"; (c) "the TaxCalculator class"; (d) "the external payment gateway (Stripe)"; (e) "the orders controller inside the API".

See solution
  • (a) The customer who buys → Context (level 1). It's a person who uses the system; people appear in the Context (and usually repeat as decoration in the Container). It's an actor of the world around the system.
  • (b) The search index (Elasticsearch) → Container (level 2). It's a separately deployable piece, with its technology. A classic container.
  • (c) The TaxCalculator class → Code (level 4). It's a concrete class; it lives at the deepest level, inside a component.
  • (d) The external payment gateway (Stripe) → Context (level 1). It's an external system Mercado talks to; external systems appear in the Context (and as decoration in the Container).
  • (e) The orders controller inside the API → Component (level 3). It's a grouping of code with a responsibility, inside a container (the API). That's level 3.

The moral: each element has a natural level. When you mix them —the customer, the search index, the class, and the controller on the same sheet— you produce the spaghetti diagram, because you're putting the world, the city, the neighborhood, and the street on a single map.

Exercise 2 — Go up or down? A dev is looking at Mercado's Container diagram and says: "I need to understand exactly what the component that calculates taxes inside the API does". Another, a manager, looks at the same diagram and says: "it's not clear to me what all this is for in the business". In which direction should each one move along the C4 ladder, and to which level do they arrive?

See solution

The dev needs to go down (get closer, more detail). They're at the Container (level 2) and want to see the interior of a piece —the API—, so they go down to the Component (level 3), where the orders controller, the tax calculator, the payments client, etc. appear. If they needed to see the exact classes of the calculation, they'd go down one more rung to the Code (level 4), though for that it's usually better to open the real code instead of a diagram.

The manager needs to go up (move away, more context). They're looking at the Container (technical pieces with technologies) and that view doesn't answer their business question. They go up to the Context (level 1), where Mercado is a single box surrounded by its users (customers, sellers) and its external dependencies (payments, shipping). There "what is this for" answers itself: it connects buyers and sellers, charges, and ships. The same system; each one moves in the direction of their question.

Exercise 3 — The defense of C4 against UML. An experienced colleague tells you: "C4 is too simple; with four types of boxes you can't capture the richness of a system the way UML does with its dozens of diagrams". Without discrediting UML, argue why C4's simplicity is an advantage for the task of communicating, and in what concrete case it is worth going down to a richer notation.

See solution

C4's simplicity is an advantage for communicating precisely because communication succeeds when the receiver understands without training, and that requires a notation anyone can read. A five-box, four-arrow Context is understood by a VP who never saw an architecture diagram; a UML diagram with diamonds, multiplicities, and stereotypes requires the reader to know the notation, and most don't (or remember it badly). For the goal of "this person understanding the shape of the system", less notation means more audience reached. The "richness" UML captures is, many times, precision the audience doesn't need and that covers the main idea —like putting the house numbers on the country map—.

That said, C4 doesn't replace all notation: it replaces the skeleton of the communication (which zoom, for whom). When you're already at the right level and need to show something the boxes-and-arrows don't capture well —for example, the exact sequence of messages of a checkout protocol, who calls whom and in what order, with waits and responses—, there a UML sequence diagram is superior and it's worth using within the appropriate level. The rule: C4 orients and communicates the structure; a specific notation details a particular aspect once the structure is clear. They don't compete; they complement each other.

Summary and next step

In this lesson you met the C4 model: four zoom levels —Context (the world), Container (the city), Component (the neighborhood), Code (the street)—, each with its question and its audience, nested like Russian dolls where each diagram opens a box of the level above. You saw, executed, the complete ladder and its key property: the audience narrows as you go down, which is why the architect's communication work concentrates at levels 1 and 2. And you understood why "a simple notation with four levels" beats the symbol soup for the task of communicating: because communication requires legibility-without-training, and C4 provides it.

Before moving on you should be able to: name the four Cs and say what question each one answers; explain the nesting (each level opens a box of the previous one) and why you don't skip or mix levels; and correct the false friend (a "container" isn't a Docker container but any deployable piece).

What follows is leaving the theory and drawing. In lesson 3 you'll build the two maps you'll use 80% of the time: the Mercado Context for the VP (what the system does, who it talks to, five boxes with no jargon) and the Mercado Container for the dev (the deployable pieces with their technologies, nine boxes). The same system, two zooms, two audiences —and you'll see, executed, how much detail each one carries—. It's the step from "I know there are four levels" to "I know how to draw the two that matter most".

Resources