ranierif.dev

Software Engineer

Documenting Software Architectures with C4 Model in Practice
Software ArchitectureC4 ModeldocumentationDiagramsPlantuml

Documenting Software Architectures with C4 Model in Practice

When working on modern systems — often composed of multiple microservices, APIs, databases, and integrations — one of the hardest challenges is explaining the architecture to different audiences.

Traditional UML diagrams often end up either too detailed (hard to follow for non-technical people) or too abstract (not useful for developers). The C4 Model, created by Simon Brown, strikes the right balance: it allows us to visualize systems at different zoom levels, from high-level context to low-level components.

In this article, I’ll walk you through practical examples of documenting architectures using the C4 Model, with diagrams generated from code.


What is the C4 Model?

C4 stands for:

  • Context – shows the system in its environment and the main actors.
  • Containers – zoom into the system, showing applications, databases, queues, etc.
  • Components – details how a container is structured internally.
  • Code – optional, illustrates classes/functions, but often skipped in practice.

The main idea is: show the right level of detail for the right audience.


Example 1: System Context Diagram

Let’s say we are building a Payment Platform that processes credit card transactions. At the context level, we only want to show who interacts with the system and what the system is.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

Person(customer, "Customer", "User making a payment")
System(system, "Payment Platform", "Processes online payments")
System_Ext(bank, "Bank", "Handles card transactions")

Rel(customer, system, "Makes a payment")
Rel(system, bank, "Sends transaction requests")
@enduml
System Context Diagram
System Context Diagram

This diagram is perfect for stakeholders and non-technical audiences. They can clearly see that customers use our system, which in turn communicates with banks.


Example 2: Container Diagram

Zooming in, we want to show the main building blocks: API Gateway, microservices, databases, queues, etc.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(customer, "Customer")
System_Boundary(paymentSystem, "Payment Platform") {
  Container(api, "API Gateway", "Laravel", "Entry point for client requests")
  Container(service, "Payment Service", "PHP", "Handles payment logic")
  ContainerDb(db, "Transactions DB", "MySQL", "Stores payment data")
  Container(queue, "Message Queue", "SQS", "Processes async tasks")
}

Rel(customer, api, "Calls")
Rel(api, service, "Routes requests")
Rel(service, db, "Reads/Writes")
Rel(service, queue, "Publishes events")
@enduml
Container Diagram
Container Diagram

This diagram is useful for engineers and architects to discuss infrastructure and deployment.


Example 3: Component Diagram

If we need to go deeper, we can zoom into a single container, like the Payment Service, and show its internal components.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

Container_Boundary(paymentService, "Payment Service") {
  Component(controller, "PaymentController", "Handles incoming HTTP requests")
  Component(processor, "PaymentProcessor", "Business logic for processing payments")
  Component(repo, "TransactionRepository", "Manages database access")
}

Rel(controller, processor, "Delegates")
Rel(processor, repo, "Reads/Writes data")
@enduml
Component Diagram
Component Diagram

This level of detail is mainly for developers onboarding into the project, since it reflects how the code is structured.


Benefits of Using C4 Model

  • Clarity for different audiences – business sees the big picture, developers see details.
  • Documentation as code – diagrams can be versioned along with the codebase (e.g., PlantUML + Git).
  • Consistency – everyone speaks the same “visual language”.
  • Onboarding – new developers can ramp up faster by seeing how systems are connected.

Conclusion

The C4 Model is not about replacing UML or ER diagrams — it’s about finding the right level of abstraction. By generating diagrams from code, you ensure your documentation is always up to date and easy to maintain.

Next time you start a project or need to explain an existing one, try drawing the four C’s: Context, Containers, Components, and Code. Your team (and your future self) will thank you.

✅ If you want to try it out, start with C4-PlantUML, which I used for all the examples above.


Published on September 3, 2025