How to read the diagrams
Many lessons draw a system: a product, a data pipeline, a training or serving setup. They all use the same small drawing language, so once you can read one, you can read them all. This page teaches it from zero. You don’t need to have seen an architecture diagram before.
What the C4 model is
Section titled “What the C4 model is”An architecture diagram is a picture of a piece of software: which parts it has, who uses it and how the parts talk to each other. The trouble is that one picture can’t show everything at once. Draw every detail and nobody can read it; draw too little and it says nothing.
The C4 model fixes this by drawing the same system several times, each time zoomed in a bit further, and each drawing answers exactly one question. It was created by Simon Brown, who describes the diagrams as “maps of your code” and compares moving between them to using “Google Maps to zoom in and out of an area you are interested in” (C4 model: introduction, read 2026-10-28). It is also “notation independent”: it cares about what you show, not which boxes and arrows you use (c4model.com, read 2026-10-28). That is why this course can draw it in plain ASCII.
The four zoom levels, as maps
Section titled “The four zoom levels, as maps”Think of planning a trip with a map app.
| Level | C4 name | Map analogy | The one question it answers |
|---|---|---|---|
| L1 | System context | The country map: your city as one dot, with the roads to the cities around it | Who uses the system, and which other systems does it talk to? |
| L2 | Container | The city map: the districts inside your city and the roads between them | Which separately running parts make up the system, and how do they talk? |
| L3 | Component | The street map of one district | Which parts live inside one of those running pieces? |
| L4 | Code | The floor plan of a single building | How is one component written, class by class? |
In plain words:
- L1, system context. The system you care about is one box in the middle. Around it are the people who use it and the outside systems it depends on. No internals at all.
- L2, container. Open the box. A container here is anything that runs or stores data on its own: a web app, an API server, a model server, a database, a batch job. C4’s own definition is “a runtime boundary around some code that is being executed or some data that is being stored”, and it says plainly: “Not Docker!” (C4 model: container, read 2026-10-28). A container in C4 is not the same thing as a Docker container.
- L3, component. Open one container and show its main parts, such as the tokenizer, encoder, scoring head and calibrator inside a decision model server.
- L4, code. Open one component and show its classes and functions.
Why the course skips level 4
Section titled “Why the course skips level 4”C4’s own guide calls the code diagram “very much an optional level of detail” and answers “No” to whether it is recommended, because “most IDEs can generate this level of detail on demand” (C4 model: code, read 2026-10-28). Code also changes daily, so a drawing of it goes stale fast. When a lesson needs that level, it shows a short Python snippet instead.
The course uses L1 whenever it describes a system, L2 when a lesson builds or explains the inside of one, and L3 only where the mechanism is the lesson. For example, how decision models work draws the reference design at L3, and building the co-pilot draws one system at all three levels.
The box-and-arrow convention
Section titled “The box-and-arrow convention”Every diagram in the course follows the same rules, so you never have to guess.
1. The title line. The first line always reads C4 · L<n> <level name> · <system name>, for example C4 · L2 Container · Distro co-pilot. It tells you the zoom level and which system you are looking at before you read anything else.
2. Boxes. Each box is drawn with +---+ corners. Inside, the first line is the element type in square brackets, the second line is the name, and an optional third line says in a few words what it does. The element types are:
| Bracket | What it means |
|---|---|
[Person] | A human who uses the system |
[Software system] | The system the diagram is about (the one in focus) |
[External system] | A system someone else runs that this one talks to |
[Container: <tech>] | A separately running part, with its technology |
[Component: <tech>] | A part inside one container, with its technology |
[Database: <tech>] | A container that stores data, with its technology |
Here is what each kind of box looks like:
+--------------+ +-------------------+ +-------------------+| [Person] | | [Software system] | | [External system] || Maintainer | | Distro co-pilot | | Frontier LLM API || ships images | | answers with odds | | writes long text |+--------------+ +-------------------+ +-------------------+
+---------------------+ +----------------------+| [Container: Python] | | [Database: SQLite] || Triage worker | | Labelled outcomes |+---------------------+ +----------------------+3. Arrows. Arrows are --> sideways, or | with a v at the end going down. Each carries a short verb label saying what flows: “asks”, “scores”, “writes”. At L2 and L3 the label also names the protocol or format in parentheses, such as scores (HTTPS/JSON) or writes outcomes (SQL). Arrows point in the direction of the request, from the one who asks to the one who answers.
4. Boundaries. At L2 and L3, a dotted border made of . and : marks the edge of the system in focus, with its name on the top edge. Everything inside belongs to the system; everything outside is a person or someone else’s system.
5. Captions. Under every diagram, one to three plain sentences say what it shows. If a diagram ever confuses you, read the caption first.
A worked example at L1 and L2
Section titled “A worked example at L1 and L2”The example is an expense checker: a small company’s app where employees submit expense claims with a receipt. For each claim it asks a hosted decision model one typed question, “approve, flag or reject?”, and gets back a probability for each answer. Confident approvals go straight to accounting to be paid; anything uncertain goes to a person in finance. This is the “automate the confident cases” pattern from from probability to automation.
Level 1: system context
Section titled “Level 1: system context”C4 · L1 System context · Expense checker
+--------------------+| [Person] || Employee || wants a refund |+--------------------+ | | submits a claim | and a receipt v+--------------------+ asks "approve, +---------------------+| [Software system] | flag, reject?" | [External system] || Expense checker |----------------->| Decision model API || clears easy claims |<-----------------| returns odds |+--------------------+ probabilities +---------------------+ | | | sends | posts approved | unsure | claims | claims | v v+-----------+ +--------------------+| [Person] | | [External system] || Finance | | Accounting system || reviewer | | pays the employee |+-----------+ +--------------------+The expense checker sits in the middle, used by an employee and a finance reviewer. It relies on two outside systems: a hosted decision model that answers its typed question with probabilities, and the accounting system that pays approved claims.
How to read it, step by step:
- Read the title line. L1, system context, about the expense checker. So you expect one box for the system and no internals.
- Find the box in focus. It is the one marked
[Software system]: the expense checker. Its third line, “clears easy claims”, is its job in four words. - Find the people. Two
[Person]boxes: the employee who submits claims, and the finance reviewer who gets the unsure ones. - Find the outside systems. Two
[External system]boxes. The decision model API is someone else’s service, perhaps Jev or a model you host elsewhere; the accounting system belongs to the finance team. - Follow the arrows. The employee submits a claim. The checker asks the decision model “approve, flag or reject?” and gets probabilities back (the return arrow). Then it either posts the claim to accounting or sends it to the reviewer.
Notice what L1 leaves out: no servers, no database, no programming languages. Someone who has never written code can follow it, which is the point.
Level 2: container
Section titled “Level 2: container”Now zoom into the one box in focus. The people and outside systems stay; the expense checker opens up to show its running parts.
C4 · L2 Container · Expense checker
+------------------+ +------------------+ | [Person] | | [Person] | | Employee | | Finance reviewer | +------------------+ +------------------+ | | | submits claims | clears flagged | (HTTPS) | claims (HTTPS) v v........................ Expense checker [system] ...................: +----------------------------------------------------------+ :: | [Container: TypeScript] | :: | Web app | :: | claim form for employees, review queue for finance | :: +----------------------------------------------------------+ :: | :: | sends claims (HTTPS/JSON) :: v :: +--------------------------+ +------------------------+ :: | [Container: Python] | reads, | [Database: PostgreSQL] | :: | Claims API |--------->| Claims and decisions | :: | applies the threshold | writes | with their odds | :: +--------------------------+ (SQL) +------------------------+ :: | | ::.....|.................|...........................................: | | | asks typed | posts approved | questions | claims | (HTTPS/JSON) | (HTTPS/JSON) v v+--------------------+ +--------------------+| [External system] | | [External system] || Decision model API | | Accounting system || returns odds | | pays the employee |+--------------------+ +--------------------+Inside the expense checker are three containers: a web app both people use, a claims API that holds the business rule, and a database that keeps every claim with the probabilities it got. Only the claims API talks to the outside systems.
How to read it, step by step:
- Read the title line. L2, container. Same system, one zoom level deeper.
- Find the boundary. The dotted border named “Expense checker [system]” is the edge of the box you saw at L1. Everything inside is what that one box was hiding.
- Read each container. The bracket gives the technology: the web app is TypeScript, the claims API is Python, the store is a PostgreSQL database. The third line says what each one does.
- Follow the arrows and their protocols. People reach the web app over HTTPS. The web app sends claims to the claims API as JSON over HTTPS. The API reads and writes the database in SQL. Two arrows leave the boundary: typed questions to the decision model and approved claims to accounting, both JSON over HTTPS.
- Spot where the decision happens. The claims API “applies the threshold”: it takes the decision model’s probability for “approve” and auto-approves only above a cut-off you chose, sending the rest to the review queue. That one line is where calibration starts to matter. If the probabilities are not honest, the threshold is wrong.
Compare the two levels. L1 told you what the system does and who it touches; L2 tells you what runs where and how the parts talk. If you needed the next level, an L3 diagram would open just the claims API and show its parts, such as a state builder that turns a claim into the model’s input, a client for the decision API and the threshold rule. The course draws L3 only where those parts are the lesson.
Go further
Section titled “Go further”- c4model.com: the official site, with the full definitions of each level and abstraction.
- C4 model: container: the one word beginners trip on most, explained.
- C4 model: code: why level 4 is optional.
- In this course: anatomy of Jev (an L1 of a support desk that calls Jev), how decision models work (an L3 reference design) and building the co-pilot (L1 to L3 of one system).