Visualize Your Software Architecture With the C4 Model
Learn the C4 model in plain words. Draw Context, Container, Component, and Code diagrams for your .NET apps with Mermaid, simple examples, and clear pictures.
A map of your city
Think about Google Maps on your phone. When you first open it, you see your whole city. You can see big roads, rivers, and which neighbourhood you live in. You do not see every single house yet. That would be too much.
Now you pinch the screen and zoom in. You see your street. Then you zoom in again, and you see your own building and the shop next door.
The map did not change the city. It only changed how much detail it showed you at each zoom level. The city-wide view is perfect for planning a long trip. The street view is perfect for finding the front door.
Software architecture works best when you draw it the same way. Most architecture diagrams fail because they try to show everything at once. Boxes and arrows go everywhere. Nobody can read them.
The C4 model is a simple set of zoom levels for software pictures. It was created by Simon Brown. Just like a map, you start far away and zoom in one step at a time. Each zoom level tells a different story to a different person.
What does C4 stand for?
C4 has four levels of zoom. The "4 C's" are:
- Context - the whole system and the world around it.
- Container - the big running pieces, like a web app, an API, and a database.
- Component - the parts inside one container.
- Code - the classes and interfaces inside one component.
Here is the key idea. You move from a wide view to a close-up view, one step at a time.
The four C4 zoom levels
Steps
Context
Whole system and users
Container
Apps, APIs, databases
Component
Parts inside one app
Code
Classes and interfaces
A common mistake is to draw every level for everything. You do not have to. Most teams draw Context and Container often, Component sometimes, and Code almost never. We will see why soon.
A simple shared language first
Before the four levels, the C4 model gives you a small set of words. If everyone uses the same words, the pictures make sense.
| Word | Plain meaning | .NET example |
|---|---|---|
| Person | A human who uses the system | A customer, an admin |
| Software System | The whole thing you are building | "Online Bookshop" |
| Container | A separately running or deployable thing | An ASP.NET Core API, a SQL database |
| Component | A grouping of code inside one container | OrderService, PaymentController |
| Relationship | An arrow showing who talks to whom | "Web app calls API over HTTPS" |
Note that "container" here does not mean a Docker container. In C4, a container is anything that runs on its own or ships on its own. A web app is a container. A database is a container. A console worker is a container. Sometimes it runs in Docker, sometimes it does not. The word is older than Docker.
Level 1: The System Context diagram
This is the most zoomed-out view. It answers one question: how does our system fit into the world?
You draw your system as a single box in the middle. Around it, you draw the people who use it and the other systems it talks to. You do not show any inside detail. None.
This diagram is for everyone, including non-technical people like a product owner or a manager. They should be able to read it without help.
Let us imagine an online bookshop. Customers buy books. The shop sends emails and takes card payments through other companies.
Look at how calm this picture is. One box for our system. A person. Two outside systems. A child could follow it. That is the point. The Context diagram is a conversation starter, not a deep technical drawing.
Level 2: The Container diagram
Now we zoom in once. We open the bookshop box and look inside. We see the big running pieces.
Each container is something you build, run, and deploy on its own. For our bookshop, we might have a web app for customers, an API that holds the business rules, and a database that stores the data.
This diagram is for technical people: developers, testers, and operations folk. It shows the shape of the system. You can see there is one web app, one API, and one database. You can see what talks to what.
A small but powerful tip: write the technology on each container. "Blazor", "ASP.NET Core", "SQL Server". And write the protocol on each arrow, like "JSON over HTTPS". These two habits remove a lot of confusion in meetings.
Here is a tiny slice of what the API container might expose. Even a Container diagram makes more sense when you can picture the real entry points.
// A minimal API endpoint inside the "Bookshop API" container.
// In C4 terms, this container talks to the database container.
app.MapGet("/books/{id}", async (int id, BookshopDb db) =>
{
var book = await db.Books.FindAsync(id);
return book is null
? Results.NotFound()
: Results.Ok(book);
});The route above is written as GET /books/{id}. The web app calls it, the API reads from the database, and a book comes back. That single arrow on the Container diagram hides this real call.
Level 3: The Component diagram
Zoom in one more step. This time we open one container and look at the parts inside it. We pick the Bookshop API.
A component is a grouping of related code with a clear job. In .NET, a component is often a service class, a handler, or a controller plus its helpers. It is bigger than a single class but smaller than a whole container.
Now we can see how a request flows through the API. The controller receives the call. It hands work to the order service. The service saves data through a repository and takes money through a payment client.
Here is what one of those components might look like in code. The OrderService is the box in the middle of the diagram.
public class OrderService
{
private readonly IOrderRepository _repository;
private readonly IPaymentClient _payment;
public OrderService(IOrderRepository repository, IPaymentClient payment)
{
_repository = repository;
_payment = payment;
}
public async Task<OrderResult> PlaceOrderAsync(Order order)
{
await _repository.SaveAsync(order);
var charge = await _payment.ChargeAsync(order.Total);
return new OrderResult(order.Id, charge.Success);
}
}See how the diagram and the code match? OrderService depends on IOrderRepository and IPaymentClient. Those are the two arrows leaving the order service box. When the picture matches the code, new teammates trust the picture.
A word of warning. Component diagrams go out of date fast, because code changes fast. Only draw them for the parts that are tricky or important. Do not draw them for every container.
Level 4: The Code diagram
The last and most zoomed-in level shows the classes and interfaces inside one component. It is basically a UML class diagram.
Most teams almost never draw this level by hand. Why? Because your IDE already shows it. Visual Studio and Rider can generate class diagrams for you. The code itself is the most up-to-date Code diagram you will ever have. So save your effort for the higher levels.
How the levels fit together
The big idea is one smooth zoom. Each box on one diagram becomes the whole picture on the next.
Zoom from world to code
Steps
System box
Open it to see containers
Container box
Open it to see components
Component box
Open it to see classes
Class
The real code
Think back to Google Maps. The city opens into a neighbourhood. The neighbourhood opens into a street. The street opens into a building. Same idea, just for software.
Drawing C4 with Mermaid in your repo
You can draw C4 diagrams many ways: on a whiteboard, in slides, or with tools like Structurizr or PlantUML. For most .NET teams, Mermaid is the sweet spot. The diagram is plain text, so it lives next to your code in Git. Reviewers can read changes in a pull request, and the picture cannot drift away into some forgotten wiki.
Mermaid even has special C4 keywords. Here is the same Context diagram written in Mermaid's C4 style.
C4Context
Person(customer, "Customer", "Buys books")
System(shop, "Online Bookshop", "Sells books online")
System_Ext(email, "Email Service", "Sends emails")
System_Ext(pay, "Payment Gateway", "Takes card payments")
Rel(customer, shop, "Browses and buys")
Rel(shop, email, "Sends order emails")
Rel(shop, pay, "Charges the card")Whether you use the plain flowchart style we used earlier or the special C4Context style is up to you and your tooling. Both tell the same story. Pick whichever renders cleanly where you work.
When to draw each level
You do not need all four diagrams for every project. Here is a simple guide.
| Level | How often to draw it | Who reads it |
|---|---|---|
| Context | Almost always | Everyone, even non-technical people |
| Container | Almost always | Developers, testers, operations |
| Component | Sometimes, for tricky parts | Developers working in that area |
| Code | Rarely, let the IDE do it | Developers, only when needed |
If you only ever draw the Context and Container diagrams, you are already far ahead of most teams. Those two levels give the most value for the least effort, and they stay useful the longest.
A note on tools and licences
The C4 model is free and open. There is no licence to buy. Simon Brown also built a tool called Structurizr for bigger setups, and it has both free and paid options. But you never have to use it. Mermaid, PlantUML, and even a whiteboard are all fine.
This is different from some popular .NET libraries that recently changed their pricing. For example, MediatR and MassTransit are now commercially licensed for many uses. The C4 model has no such catch. It is a way of thinking, and thinking is free.
A common mistake to avoid
Many people draw one giant diagram with everything on it: users, web apps, databases, queues, classes, all mixed together. They feel proud of it. But nobody can read it, and it is wrong within a week.
The C4 model fixes this by giving each diagram one zoom level and one audience. A Context diagram for the manager. A Container diagram for the team. A Component diagram only when a part is hard to understand. Keep each picture small, and keep each picture honest.
Putting it all together with .NET
Imagine you join a new .NET team next month. They hand you four small diagrams instead of a 40-page document. In ten minutes you know:
- From Context: the system sells books and uses an email and a payment provider.
- From Container: there is a Blazor web app, an ASP.NET Core API, and a SQL Server database.
- From Component: inside the API, orders flow through a controller, a service, a repository, and a payment client.
- From Code: the
OrderServicedepends on two interfaces, which you can also see right in the code.
That is the gift of the C4 model. New people get up to speed quickly, meetings stay calm, and the pictures keep matching the real system because they are simple enough to maintain.
References and further reading
- The C4 model (official site) - Simon Brown's home page for the model, with full descriptions of each level.
- C4 model on Wikipedia - a neutral overview of the history and ideas.
- Mermaid C4 diagram syntax - how to write C4 diagrams as text with Mermaid.
- Practical creation of C4 Model diagrams with Structurizr (Code4IT) - a hands-on .NET-friendly walkthrough.
- What is the C4 model? (IcePanel) - a friendly community explainer.
Quick recap
- The C4 model draws software like a map: you zoom in one step at a time.
- The four levels are Context, Container, Component, and Code.
- Context shows your system and the world. It is for everyone.
- Container shows the big running pieces, like a web app, an API, and a database. Write the technology and the protocol on it.
- Component shows the parts inside one container. Draw it only for tricky areas.
- Code shows classes inside one component. Let your IDE do this for you.
- A C4 "container" is anything that runs or deploys on its own. It is not only a Docker container.
- Mermaid is a great free way to keep C4 diagrams in Git, right next to your code.
- Most teams get the most value from just the Context and Container diagrams.
Related Posts
Clean Architecture Folder Structure in .NET: A Simple Guide
Learn how to organise a .NET solution with Clean Architecture. Understand the Domain, Application, Infrastructure, and Presentation layers, the dependency rule, and the exact folders, with diagrams and examples.
What Is a Modular Monolith? A Beginner-Friendly Guide for .NET
Understand the modular monolith in simple words: one app, strong internal walls. Learn how it compares to monoliths and microservices, why it is the 2026 default for most .NET teams, and how to build one.
Understanding Microservices: Core Concepts and Benefits for .NET
A beginner-friendly guide to microservices in .NET: what they are, the core ideas behind them, their real benefits and trade-offs, and when to use them.
Synchronous vs Asynchronous Communication in Microservices (.NET Guide)
A simple, friendly guide to synchronous vs asynchronous communication in microservices, with .NET examples, diagrams, tables, and clear rules on when to use each.
12 Essential Distributed System Design Patterns Every Architect Should Know
A friendly guide to 12 distributed system design patterns in .NET — saga, CQRS, outbox, circuit breaker, retry, sidecar, and more, with diagrams and code.
Where Vertical Slices Fit Inside the Modular Monolith
A simple guide to how vertical slices live inside the modules of a modular monolith in .NET, with diagrams, code, tables, and everyday examples.