The Problem Everyone Ignores
Let's be honest: nobody reads architectural documentation. It becomes outdated within a week, lives in Confluence as a monument to the past, and newcomers learn through "can I ask you something?". Diagrams turn into art objects — beautiful but useless.
In 15 years, I've seen hundreds of architectural diagrams. The problem isn't that they don't exist. The problem is they don't work. They're either too abstract ("boxes and arrows about nothing") or too detailed ("where's the actual architecture?").
C4 model by Simon Brown solves this elegantly: four levels of abstraction, like Google Maps. You can look at a city from bird's-eye view or zoom into a specific street. Each level answers its own question and is useful for its audience.
I've been using C4 in all projects since 2019. It's not a panacea, but I haven't found a better tool for architecture visualization.
TL;DR: Who Should Read and Why
This article provides different value for different roles. Here's what you'll find:
👨💻 Developer (Junior → Middle)
Read: Level 1-3, Practical Rules, Common Pitfalls Why: Understand system structure, where to put new code, how to read architecture diagrams Time: 10 minutes Benefit: Cut onboarding from 3 weeks to 3 days, stop fearing the "big picture"
🏗️ Architect / Tech Lead
Read: Everything + CJM+C4 section, Advanced Techniques, Automation Why: Learn to design architecture the whole team understands, connect UX with technical decisions Time: 30 minutes Benefits:
- Speed up architectural decisions from 5 days to 1 day
- Get a framework for connecting CJM and architecture
- Learn to automate documentation
💼 CTO / Engineering Manager
Read: TL;DR, ROI metrics, Real Cases, Implementation Checklist Why: Get numbers and process for implementing architectural discipline Time: 15 minutes Benefits:
- −87% onboarding time for new developers
- −80% errors due to architecture misunderstanding
- −75% documentation time (through automation)
- Architecture transparency for all stakeholders
🎨 Product Manager / UX Designer
Read: C4 + CJM section, Level 1-2 Why: Understand how your user journeys translate to technical architecture Time: 15 minutes Benefit: Learn to validate CJM through technical implementation, find gaps between promises and capabilities
Quick Start: If You Only Have 1 Hour for C4
No time to read the whole article? Here's the express plan.
5 Must-Do Things (60 minutes)
1. Create file docs/architecture/system-context.md (10 min)
# Architecture: System Context
## Our System
[Your product name] — [one sentence, what it does]
## Users
- **[Role 1]**: [what they do]
- **[Role 2]**: [what they do]
## External Systems
- **[System 1]**: [why we integrate]
- **[System 2]**: [why we integrate]
## Diagram
[Draw in Mermaid or paste screenshot from whiteboard]2. Draw Level 1 on whiteboard/Miro (15 min)
- One box — your system
- Stick figures — user roles
- Boxes — external systems
- Arrows with labels: who talks to whom
3. Create Level 2: Containers (20 min)
- What applications/services do you have?
- Databases, queues, caches
- How are they connected?
Use Mermaid Live Editor — paste text, get diagram.
4. Add technologies in square brackets (5 min)
Web App [React + Next.js]API [Python + FastAPI]Database [PostgreSQL 15]
5. Put in main repository README.md (10 min)
## Architecture
See [docs/architecture/system-context.md](docs/architecture/system-context.md)
**Quick overview:**
- Level 1 (Context): [link to diagram]
- Level 2 (Containers): [link to diagram]Congratulations! You have basic architectural documentation. This is enough for 80% of tasks. Everything else — as needed.
3 Deadly Sins (What NOT to Do)
❌ Sin #1: Draw diagrams in PowerPoint/draw.io or store in Confluence/Wiki
- Why bad: impossible to version with code, becomes outdated in a week
- What to do: Only Diagrams as Code in Git repository. Mermaid, PlantUML, Structurizr DSL
- Rule: If diagram isn't in same repo as code — it's already outdated
❌ Sin #2: Make diagrams "for the sake of it" and store separately
- Why bad: nobody will use them, team doesn't even know they exist
- What to do:
- Store in project root:
/docs/architecture/ - Link from
README.mdas first link - Present at every onboarding
- Update in same PR as code
- Store in project root:
❌ Sin #3: Draw Level 3-4 for everything at start
- Why bad: waste of time, details will become outdated, team will lose trust
- What to do: Level 1-2 first, Level 3 — only for complex parts as needed
3 Arguments to Convince Your Team
For developers: "Newcomers will ramp up in 3 days instead of 3 weeks. Fewer 'how does this work?' questions"
For managers: "1,735% ROI in first year. Pays off in a month. Here's the table with numbers [link to ROI section]"
For CTO: "Architecture transparency for investors, auditors, partners. One glance — whole picture"
What is C4 Model
C4 stands for Context, Containers, Components, Code — four levels of abstraction for describing software system architectures.
C4 Philosophy
Key idea: architecture as a map with different zoom levels.
- Level 1 (Context): Airplane view — system surrounded by users and other systems
- Level 2 (Containers): City view — what major parts the system consists of
- Level 3 (Components): Street view — what each part consists of
- Level 4 (Code): Building blueprint — classes, interfaces, structures
The term "Container" here is not about Docker. Container is a separately deployable/runnable unit: web application, mobile app, database, microservice, message queue.
Principles That Make C4 Work
- Abstraction through scale — each level is useful on its own
- Audience and purpose — diagrams for people, not for beauty
- Evolution over static — diagrams should update like code
- Minimalism — only important things, no information noise
- Consistent notation — same symbols across all levels
Personal Opinion: IDEF-0 and Déjà Vu Feeling
Honestly, when I first saw C4, I had a strange déjà vu feeling. I remembered IDEF-0 (Integration Definition for Function Modeling) — a functional modeling methodology popular in the 90s and 2000s. I always liked IDEF-0 for its structure and rigor: hierarchical decomposition, inputs-outputs-mechanisms-controls, sequential detailing levels.
C4 is essentially reinventing the wheel. The idea of multi-level abstraction isn't new: IDEF-0 did this 40 years ago, UML Component Diagrams — 25 years ago, Kruchten's 4+1 Architectural View Model — also not born yesterday.
But! This déjà vu doesn't diminish C4's advantages. Why did C4 succeed where IDEF-0 remained niche?
- Easy entry: IDEF-0 required training and certification, C4 can be learned in an hour
- Modern context: cloud, microservices, DevOps — C4 speaks today's language
- Diagrams as Code: IDEF-0 was drawn in specialized editors, C4 lives in Git
- Pragmatism vs formalism: C4 doesn't require IDEF-0's strictness, it's more flexible and friendly
So yes, C4 is new packaging of old ideas. But sometimes packaging determines whether a tool gets used or gathers dust in system analysis textbooks.
Comparison Table: C4 vs Other Methodologies
To understand how C4 differs from competitors, here's an honest comparison:
| Criteria | C4 Model | ArchiMate | UML Component | IDEF-0 | 4+1 View Model |
|---|---|---|---|---|---|
| Learning curve | 1-2 hours | 1-2 weeks | 2-3 days | 3-5 days | 1-2 days |
| Notation simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| For DevOps/CI/CD | Excellent | Medium | Poor | Poor | Medium |
| Automation | High | Low | Medium | Low | Medium |
| Diagrams as Code | Yes (DSL) | Partial | Yes (PlantUML) | No | Partial |
| Microservices support | Excellent | Good | Medium | Poor | Good |
| Enterprise adoption | Growing | Standard | Exists | Historical | Niche |
| Tooling | Много | Free & paid options | Medium | Outdated | Few |
| Active community | Yes | Niche | Large | Dead | No |
| Suitable for startups | ⭐⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐ | ⭐ | ⭐⭐⭐ |
| Suitable for enterprise | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Implementation cost | Low | High | Medium | Medium | Low |
| Years of existence | since 2014 | since 2009 | since 1997 | since 1981 | since 1995 |
When to choose C4:
- Need quick start (startup, MVP)
- Team wants simplicity and practicality
- Have or plan microservices
- Want Diagrams as Code in Git
- Need CI/CD integration
When to choose ArchiMate:
- Enterprise with strict standards
- Need certification and compliance
- Describing not just IT but business processes
- Ready to learn complex notation (free Archi available, paid Sparx Enterprise Architect, BiZZdesign)
When to choose UML:
- Describing object-oriented system
- Need detailed class diagrams
- Team already knows UML
- Academic environment / education
When to choose IDEF-0:
- Government project with GOST requirement
- Describing production processes
- Need strict formalization
- Have legacy company standards
When to choose 4+1:
- Need different views for different stakeholders
- Complex system with many aspects
- Combining with other notations
My choice: C4 for 90% of projects. ArchiMate — only in enterprise with strict compliance requirements. UML — for detailing classes in critical components. IDEF-0 — if client requires by contract. 4+1 — never, C4 covers same needs simpler.
Level 1: System Context — Bird's-Eye View
Why Needed
Context diagram answers questions:
- Who uses the system?
- What external systems does it interact with?
- What are the responsibility boundaries?
Audience: everyone — from business to developers.
What to Include
- Your system (one box)
- Users (roles, not specific people)
- External systems (payments, CRM, email services)
- Interactions (who talks to whom and why)
Example: Online Learning Platform
Practical Rules
What works: - One box for your system, even if 50 microservices inside - User roles, not "manager Vasya" - Verbs on arrows: "sends order", not just "uses"
Anti-patterns:
- ❌ Inflating Context to Containers level — "let's show databases here"
- ❌ Showing internal structure — that's Level 2
- ❌ Technical protocol details — not here
Level 2: Container Diagram — Architectural Zoning
Why Needed
Container diagram reveals the system's major building blocks:
- What applications/services does the system consist of?
- How do they interact?
- What technologies are used?
Audience: architects, tech leads, DevOps, senior developers.
What to Include
- Web applications (SPA, MPA)
- Mobile applications (iOS, Android)
- Backend services (API, workers)
- Databases (SQL, NoSQL, caches)
- Message queues (Kafka, RabbitMQ)
- External systems (from Level 1)
Example: Same Learning Platform
Practical Rules
What to show:
- Technology stack in labels:
API Gateway [Kong] - Interaction protocols: HTTP/REST, gRPC, GraphQL, AMQP
- Replicated databases as separate containers (if important)
Grouping principles:
- If can be deployed separately — it's a Container
- If scales independently — it's a Container
- If has its own CI/CD pipeline — definitely a Container
Common mistake: showing all microservices on one diagram. If you have 40 services — group by domains or make several Level 2 diagrams for different parts.
Why Specify Technologies
This isn't academic pedantry. Technologies on Container diagram:
- Help newcomers understand project stack in 30 seconds
- Reveal the zoo — if you have 7 programming languages, maybe time to think?
- Simplify estimation — architect immediately sees integration complexity
Level 3: Component Diagram — Container Internals
Why Needed
Component diagram shows structure of one Container:
- What modules/components inside?
- What responsibilities does each have?
- How do they interact?
Audience: developers, tech leads, architects (for detailed design).
What to Include
- Components — logical modules with clear responsibilities
- Interfaces — public APIs of components
- Dependencies — who depends on whom
- External dependencies — databases, queues, other containers
Example: Course Service Internals
Practical Rules
What is Component in C4:
- Group of related functions/classes with clear responsibility
- Has public interface (API)
- Can be replaced with alternative implementation
Component examples:
- Controllers (MVC)
- Services / Use Cases
- Repositories / Data Access
- Gateways / Adapters
- Middleware / Interceptors
Tip: Component diagrams aren't mandatory for all containers. Draw them only for complex services where architecture is non-obvious. For simple CRUD API, Level 2 is enough.
Level 3 Anti-patterns
❌ Too detailed: showing every class — that's Level 4 ❌ Too abstract: "Business Logic" as one box — useless ❌ Mixing layers: UI components and business logic at same abstraction level
Right granularity: 5–12 components per diagram. Less — combine, more — decompose Container or group components.
Level 4: Code — Implementation Details
Why Needed (spoiler: often not needed)
Code diagrams show classes, interfaces, data structures. This is UML class diagrams.
Problem: these diagrams become outdated faster than you can draw them.
C4 solution: use auto-generation tools (PlantUML, Structurizr, IDE plugins) or replace Code diagrams with good README in the module.
When Level 4 is Useful
- Complex design patterns (Strategy, Visitor, Builder)
- Public APIs of libraries
- Critical business logic with non-obvious connections
Example (simplified)
Honestly: I draw Code diagrams by hand once a quarter when explaining complex business logic in whiteboard sessions. In repositories they don't live — become outdated instantly.
Practical Principles of C4 Application
Theory is good, but it's nothing without combat experience. Here are key principles that have proven themselves in practice.
1. Diagrams as Code
The ONLY way to keep documentation current is the "Architecture as Code" approach.
Traditional approaches (drawings in Confluence, diagrams in Figma) are doomed from the start. They become outdated within 2-3 weeks and no one updates them.
Write diagrams as text:
Mermaid (simple, built into GitLab/GitHub):
PlantUML (more powerful, requires plugin):
@startuml
!include C4_Context.puml
Person(user, "User")
System(platform, "Platform")
System_Ext(payment, "Payment")
Rel(user, platform, "Uses")
@endumlStructurizr DSL (most powerful, for large systems):
workspace {
model {
user = person "User"
platform = softwareSystem "Learning Platform"
payment = softwareSystem "Payment System"
user -> platform "Studies on"
platform -> payment "Processes payments"
}
views {
systemContext platform {
include *
autolayout lr
}
}
}
Why this is the only working approach:
- Version control — diagrams in Git next to code
- Review — changes go through PR with discussion
- Automation — can generate from code, test in CI/CD
- Synchronization — one source of truth for code and docs
- Search — full-text search works (try finding something in PNG)
My choice: Mermaid for simple cases (renders directly in GitLab/GitHub), PlantUML for complex systems, Structurizr DSL for enterprises.
2. Store diagrams next to code
Anti-pattern:
- Diagrams in Confluence
- Docs in separate repository
- Drawings in Google Drive
- "Architecture portal" on SharePoint
Practical approach:
project/
docs/
architecture/
00-overview.md # System Context
01-containers.md # Container diagram
02-auth-service.md # Components of Auth Service
adr/ # Architecture Decision Records
001-use-postgres.md
002-use-event-sourcing.md
src/
auth-service/
README.md # Links to docs/architecture/02-auth-service.md
Why it works:
- Proximity — developers see docs in the repository
- Review — changes to architecture go through code review
- Relevance — updating a service = updating its docs in the same PR
- Onboarding — new team members immediately see the structure
In 10 years, I have NEVER seen current architecture documentation in Confluence/Wiki.
It always turns into an "abandoned cemetery" of outdated diagrams. Documents live only when they're in Git next to the code.
3. Make diagrams "live"
Level 1: Generation from code
Python example:
# services/discovery.py
import yaml
from pathlib import Path
def generate_container_diagram():
"""Generate C4 Container diagram from docker-compose.yml"""
with open("docker-compose.yml") as f:
compose = yaml.safe_load(f)
mermaid = ["graph TB"]
for service, config in compose["services"].items():
image = config.get("image", "unknown")
mermaid.append(f' {service}["{service}<br/>{image}"]')
# Dependencies from environment variables
for service, config in compose["services"].items():
env = config.get("environment", {})
for key, value in env.items():
if "DATABASE" in key:
mermaid.append(f" {service} --> postgres")
elif "REDIS" in key:
mermaid.append(f" {service} --> redis")
return "\n".join(mermaid)
if __name__ == "__main__":
diagram = generate_container_diagram()
Path("docs/architecture/01-containers.md").write_text(
f"# Container Diagram\n\n```mermaid\n{diagram}\n```"
)Level 2: Testing for synchronization
# tests/test_architecture_sync.py
import pytest
import yaml
import re
def test_all_services_documented_in_c4():
"""Check that all services from docker-compose are in C4 diagrams"""
# Read actual services
with open("docker-compose.yml") as f:
compose = yaml.safe_load(f)
actual_services = set(compose["services"].keys())
# Read documented services from C4
with open("docs/architecture/01-containers.md") as f:
content = f.read()
# Find all service mentions in Mermaid diagrams
documented_services = set(
re.findall(r'(\w+)\["', content)
)
missing = actual_services - documented_services
assert not missing, f"Services not documented: {missing}"
def test_all_databases_have_backups():
"""Check that all stateful services have backup configuration"""
with open("docker-compose.yml") as f:
compose = yaml.safe_load(f)
stateful = {"postgres", "redis", "mongodb"}
for service in stateful:
if service in compose["services"]:
volumes = compose["services"][service].get("volumes", [])
assert any("backup" in v for v in volumes), \
f"{service} has no backup volume"Level 3: CI/CD automation
# .gitlab-ci.yml
architecture-check:
stage: test
script:
- python services/discovery.py # Generate diagram
- git diff --exit-code docs/architecture/ # Check for changes
# If there are changes - fail the pipeline
only:
changes:
- docker-compose.yml
- kubernetes/*.yamlThis ensures:
- Forgot to update C4 when adding a new service → pipeline fails
- Added a database without backups → tests fail
- Changed infrastructure → diagram auto-updates
4. Legend and conventions
Each diagram should have a legend so everyone interprets it the same way:
Legend:
[Blue box] — internal service (we own it)
[Gray box] — external system (third-party)
[Red border] — contains PII (personal data)
[Dashed line] — asynchronous communication (message queue)
[Solid line] — synchronous (HTTP/gRPC)
[Lock icon] — requires authentication
Example with color coding:
5. Audience and depth
System Context (Level 1): For everyone (CEO, investors, clients)
- No technical details
- Business terminology
- "What does the system do?"
Containers (Level 2): For architects and tech leads
- General technology stack
- Integration points
- "What are the main moving parts?"
Components (Level 3): For development teams
- Internal structure of services
- Design patterns
- "How is it organized inside?"
Code (Level 4): For developers working with a specific module
- Classes, interfaces
- Critical algorithms
- "How exactly does it work?"
Practical rule: If the diagram doesn't fit on one screen (or one printed A4 page) — you've gone too deep. Split into multiple diagrams.
6. Updates and relevance
When to update C4:
✅ Always:
- Added a new service/component
- Changed data flow
- Integrated with an external system
- Changed authentication/authorization
- Migrated to a new technology
⚠️ Sometimes:
- Refactored code inside a component (if it didn't change interfaces)
- Updated a library version (if it didn't change architecture)
- Fixed a bug (if it didn't change structure)
❌ Never:
- Changed HTML markup
- Updated text on a page
- Changed CSS styles
Automation:
# Git hook to remind about documentation
# .git/hooks/pre-commit
#!/bin/bash
if git diff --cached --name-only | grep -q "docker-compose.yml"; then
echo "⚠️ You changed docker-compose.yml"
echo " Don't forget to update docs/architecture/01-containers.md"
echo ""
read -p "Architecture documentation updated? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fiCommon Pitfalls: 10 Antipatterns I've Encountered
Let me share the mistakes I've made and seen in real projects. Learning from others' mistakes is cheaper than from your own.
1. "C4 as religion"
Symptom: Everything must be strictly according to Simon Brown, any deviation is heresy.
Problem:
- Spend 2 weeks creating "perfect" Level 4 diagrams for CRUD
- Force the team to use Structurizr when 90% of cases are covered by Mermaid
- Create 47 diagrams that no one looks at
Solution: Use C4 as a tool, not a goal. If a component is simple — a paragraph of text is enough. Diagrams are needed where they save time, not where they "should be".
I once insisted on a complete set of C4 diagrams for a startup with 3 people. We spent a month on documentation instead of product. The startup died. The documentation was beautiful.
2. "Illusion of clarity"
Symptom: Beautiful diagrams, but everyone understands them differently.
Problem:
- No legend — everyone interprets colors and arrows in their own way
- No description — the diagram is "self-documenting" (spoiler: it's not)
- No context — unclear what level of abstraction this is
Example of a bad diagram:
What is this? Services? Functions? Teams? No one knows.
Solution:
3. "Architecture for a checkbox"
Symptom: C4 is created for an audit/certification, not for work.
Problem:
- Created once, never updated
- Stored in a separate repository/wiki
- No one knows it exists
Real case:
Client hired me for a "C4 audit". They had 127 (!) PlantUML files. I asked: "When was this last updated?"
Answer: "Two years ago, for ISO certification."
I checked the current codebase — 60% of the services from the diagrams no longer existed, 40% of the new ones weren't documented.
Solution:
Architecture documentation lives only when it's:
- In the repository next to the code
- Updated in the same PR as the code
- Tested in CI/CD (auto-generation or consistency tests)
4. "Premature detailing"
Symptom: Start with Level 4 (code) instead of Level 1 (context).
Problem:
- Spend a week drawing class diagrams
- No one understands how the system works as a whole
- When the architecture changes, all diagrams go in the trash
Real case:
A team came to me: "We have 300 PlantUML diagrams, but new developers still don't understand the system."
I looked — all diagrams were Level 3-4 (components and classes). There wasn't a single Level 1 (System Context).
Solution:
Always start from the top:
- Level 1 — who uses the system, what external systems are there
- Level 2 — what are the main parts of the system
- Level 3 — how complex services are structured
- Level 4 — only for the most critical/complex components
5. "Forgot about security"
Symptom: The diagram doesn't show which components handle sensitive data.
Problem:
- Can't conduct a security audit
- Unclear where to apply encryption
- Difficult to assess GDPR/PII compliance
Example of a diagram without security:
All services look the same, but the database contains PII.
Solution:
Immediately visible:
- DB contains sensitive data (red border)
- API requires authentication (🔐)
- All connections are encrypted
6. "Diagrams live separately from reality"
Symptom: The diagram shows version 1.0, production is running version 3.5.
Problem:
- No automation — diagrams are drawn manually
- No checks — no one verifies synchronization with code
- No culture — no one updates docs
Real case:
Client: "We have Container diagrams in Confluence."
Me: "When was it updated?"
Client: "Last year when we started the project."
Me: "How many services do you have now?"
Client: "23."
Me: "The diagram shows 7."
Solution:
Approach 1: Generation from code
# Auto-generate diagram from docker-compose.yml
python scripts/generate_c4_from_compose.py > docs/01-containers.mdApproach 2: Integration testing
def test_all_services_documented_in_c4():
"""Check that all services from docker-compose are in C4"""
# Read actual services from docker-compose.yml
with open("docker-compose.yml") as f:
compose = yaml.safe_load(f)
actual = set(compose["services"].keys())
# Read documented services from C4 Container diagram
with open("docs/architecture/01-containers.md") as f:
content = f.read()
# Extract service names from Mermaid diagram
documented = set(re.findall(r'(\w+)\["', content))
# If a service exists but isn't documented - test fails
missing = actual - documented
assert not missing, f"Services not in C4: {missing}"Approach 3: CI/CD checks
# .gitlab-ci.yml
test-architecture-sync:
script:
- pytest tests/test_architecture_sync.py
only:
changes:
- docker-compose.yml
- kubernetes/*.yaml7. "Everything in one diagram"
Symptom: One giant diagram with 50+ elements.
Problem:
- Doesn't fit on screen
- Can't understand anything
- Can't print
Example of a bad diagram:
[Giant diagram with 50 boxes, 100 arrows,
font size 6px, no one can read it]
Solution:
Split into multiple focused diagrams:
docs/architecture/
01-context.md # System Context (all external systems)
02-containers.md # All containers of the system
03-auth-service-components.md # Auth Service components
04-course-service-components.md # Course Service components
05-payment-flow.md # Payment scenario (dynamic)
06-deployment-prod.md # Deployment diagram
Each diagram — one screen, one topic.
8. "No one knows what level this is"
Symptom: Mixing different abstraction levels in one diagram.
Problem:
This mixes:
- Level 1 (User — external actor)
- Level 2 (WebApp, API — containers)
- Level 3 (AuthController — component)
- Level 4 (bcrypt.hash — code)
Solution:
Each diagram — one level:
Level 2: Containers
Level 3: Auth Service components
9. "Technology instead of purpose"
Symptom: The diagram shows "PostgreSQL", "Redis", "Kafka", but it's unclear what they're for.
Bad:
What's stored in Postgres? Why is Redis needed? What does Kafka do?
Good:
Now it's clear:
- Postgres — long-term data storage
- Redis — temporary session cache
- Kafka — asynchronous event exchange
10. "Forgot about operations"
Symptom: The diagram shows functional components, but doesn't show how it all works in production.
Problem:
- Unclear how deployment happens
- No monitoring/logging
- No disaster recovery strategy
Solution:
Add a Deployment diagram (C4 extension):
Now visible:
- How many API instances (3 pods)
- Databases have replication (Multi-AZ)
- There's monitoring (Prometheus + Grafana)
- Everything is in Kubernetes
Key rule: If you recognize yourself in these antipatterns — good! Recognizing a problem is the first step to solving it.
Real Cases: C4 in Action
Theory is good, but practice is better. Here are three real stories from my consulting experience (company names changed for confidentiality).
Case 1: "Microservice Chaos" — Fintech Startup
Problem:
Fintech startup, 25 microservices, 15 developers. New team members couldn't understand the system architecture for 3 weeks. Each asked: "Where does the payment flow go?", "Which service is responsible for KYC?", "Why do we have 3 databases?"
No one could answer. The tech lead left 4 months ago, taking the knowledge with him.
What we did:
Week 1: Created Level 1 (System Context)
Result: Everyone understood "what the system does as a whole" in 30 minutes.
Week 2: Created Level 2 (Containers)
Mapped all 25 microservices to business capabilities:
Result: Payment flow became obvious, team leads could distribute tasks by services.
Week 3-4: Created Level 3 for critical services
Example for Payment Service:
Results:
Business effect:
- Saved ~$45,000 on onboarding (15 days × 5 developers × $200/hour)
- Reduced time to make architecture decisions by 80%
- Found 3 duplicate services (were doing the same thing)
Case 2: "Legacy Monolith" — E-commerce Company
Problem:
E-commerce company, 10 years old monolith in PHP. 300,000 lines of code. No one knows what depends on what. Any change is like playing Russian roulette.
Question: "Can we separate catalog into a separate service?"
Answer: "We don't know, we need to investigate for 2 weeks."
What we did:
Step 1: Reverse engineering — created Container diagram from code
Wrote a Python script:
import re
from pathlib import Path
def analyze_dependencies():
"""Analyze dependencies between modules"""
modules = {}
for file in Path("src").rglob("*.php"):
content = file.read_text()
# Find module name
module = file.parent.name
# Find dependencies (use/require)
deps = re.findall(r'use\s+App\\(\w+)', content)
if module not in modules:
modules[module] = set()
modules[module].update(deps)
return modules
def generate_c4_container(modules):
"""Generate C4 Container diagram"""
mermaid = ["graph TB"]
for module, deps in modules.items():
mermaid.append(f' {module}["{module}"]')
for dep in deps:
mermaid.append(f' {module} --> {dep}')
return "\n".join(mermaid)Result: Got a diagram with REAL dependencies:
Key discovery: Circular dependency between Order and Payment!
Step 2: Created Component diagrams for the most complex modules
For the Order module:
Step 3: Created a separation plan
Based on C4, created a roadmap:
- Break circular dependency Order ↔ Payment
- Separate Auth into a service (no dependencies on it)
- Separate Catalog (depends only on Product, Inventory, Pricing)
- Separate Payment (depends on User, publishes events)
- Separate Order (depends on Payment, Catalog, Shipping)
Results:
Business effect:
- Saved ~$80,000 on investigation (2 weeks × 4 senior devs × $200/hour)
- Reduced deployment time from 2 hours to 15 minutes
- Decreased number of production incidents by 60%
Case 3: "Documentation Graveyard" — Enterprise
Problem:
Large bank, 200+ services, 50 teams. Architecture documentation exists, but:
- 80% is outdated
- Stored in Confluence (500+ pages)
- No one updates it
- New developers don't read it (because it's irrelevant)
What we did:
Step 1: Migrated to "Architecture as Code"
Created structure in Git:
architecture/
00-system-context.md # Level 1: System Context
01-containers.md # Level 2: All services
domains/
payments/
02-payment-flow.md # Level 3: Payment components
03-fraud-detection.md # Level 3: Fraud components
lending/
02-loan-origination.md
03-credit-scoring.md
Step 2: Set up auto-generation from Kubernetes
# scripts/generate_c4_from_k8s.py
import yaml
from kubernetes import client, config
def generate_container_diagram():
"""Generate C4 Container from Kubernetes deployments"""
config.load_kube_config()
v1 = client.AppsV1Api()
deployments = v1.list_deployment_for_all_namespaces()
mermaid = ["graph TB"]
for dep in deployments.items:
name = dep.metadata.name
namespace = dep.metadata.namespace
# Group by domain (namespace)
mermaid.append(f' subgraph "{namespace}"')
mermaid.append(f' {name}["{name}"]')
mermaid.append(f' end')
return "\n".join(mermaid)Step 3: Set up CI/CD checks
# .gitlab-ci.yml
architecture-sync:
stage: test
script:
- python scripts/generate_c4_from_k8s.py > architecture/01-containers-actual.md
- diff architecture/01-containers.md architecture/01-containers-actual.md
only:
changes:
- kubernetes/**/*Results:
Business effect:
- Saved ~$200,000/year on documentation maintenance
- Onboarding time reduced from 3 weeks to 5 days
- Architecture decisions are made 5x faster
ROI: Numbers That Matter
Based on my experience implementing C4 in 15+ companies:
Time Savings
| Metric | Before C4 | After C4 | Change |
|---|---|---|---|
| New developer onboarding | 18-21 days | 3-5 days | −87% |
| Architecture decision time | 3-7 days | 0.5-1 day | −80% |
| Time to find service owner | 2-4 hours | 2-5 minutes | −95% |
| Integration understanding | 1-2 days | 1-2 hours | −90% |
Quality Improvements
| Metric | Before C4 | After C4 | Change |
|---|---|---|---|
| Architecture errors in PRs | 15-20% | 2-4% | −85% |
| Production incidents | 12/month | 3/month | −75% |
| "Architecture not considered" issues | 30% | 5% | −83% |
| Documentation outdatedness | 80% | <10% | −90% |
Financial Effect
Investment (for a team of 20 developers):
- Initial implementation: 40 hours ($8,000)
- Maintenance: 2 hours/week ($4,000/year)
- Total first year: $12,000
Savings (conservative estimate):
- Onboarding: 15 days × 5 developers × $200/hour = $60,000/year
- Reduced incidents: 9 incidents × 4 hours × 5 people × $200/hour = $36,000/year
- Faster decisions: 100 decisions × 3 days × $200/hour = $120,000/year
- Total savings: $216,000/year
ROI = ($216,000 − $12,000) / $12,000 × 100% = 1,700%
Real case: One of my clients calculated ROI for C4 at 1,735% in the first year. The main effect was reduced onboarding time and fewer production incidents.
Intangible Benefits
What's hard to measure but incredibly valuable:
- Architectural thinking — developers start thinking at the system level
- Common language — everyone speaks the same terms
- Confidence — team knows the system will scale
- Transparency — management sees what's actually being built
- Knowledge transfer — knowledge doesn't leave with departing employees
Tools and Ecosystem
C4 is not tied to specific tools. You can draw diagrams in anything. But some tools are more convenient than others.
Level 1: Text-Based (Diagrams as Code)
Mermaid ⭐ My choice for 80% of cases
Pros:
- Works out of the box in GitLab/GitHub/Notion
- Simple syntax
- No additional tools needed
- Renders directly in README.md
Cons:
- Limited styling
- No auto-layout (you specify positions manually)
- For complex systems can become unwieldy
When to use: Small/medium projects, startups, internal documentation
PlantUML ⭐ For complex systems
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(user, "User")
System(platform, "Platform")
Rel(user, platform, "Uses")
@endumlPros:
- Powerful C4 library (C4-PlantUML)
- Auto-layout
- Rich styling
- Export to PNG/SVG
Cons:
- Requires PlantUML server or plugin
- More complex syntax
- Doesn't render natively in GitHub
When to use: Large systems, enterprises, when you need perfect diagrams
Structurizr DSL ⭐ For large enterprises
workspace {
model {
user = person "User"
platform = softwareSystem "Platform"
user -> platform "Uses"
}
views {
systemContext platform {
include *
autolayout lr
}
}
}
Pros:
- Most powerful (from C4 creator Simon Brown)
- One model — many views
- Version control and collaboration
- Integration with Structurizr cloud
Cons:
- Steep learning curve
- Requires Structurizr CLI or cloud
- Overkill for small projects
When to use: 50+ services, multiple teams, strict governance
Level 2: Visual Tools
draw.io (diagrams.net) — for quick sketches
Pros:
- Free
- Works in browser
- Export to PNG/SVG
- Integration with Google Drive/Confluence
Cons:
- Not "diagrams as code"
- Manual maintenance
- Difficult to version control
When to use: Prototyping, presentations, one-time diagrams
Lucidchart — for collaboration
Pros:
- Real-time collaboration
- Ready-made C4 templates
- Integration with Jira/Confluence
Cons:
- Paid ($7.95/month)
- Not "diagrams as code"
- Vendor lock-in
When to use: Non-technical stakeholders, workshops
Level 3: Platform Solutions
Structurizr Cloud — SaaS for C4
Pros:
- Official solution from C4 creator
- Version control
- Multiple workspaces
- Access control
Cons:
- Paid (from $7.50/month)
- Vendor lock-in
When to use: Enterprises with budget, strict access control requirements
IcePanel — modern C4 platform
Pros:
- Beautiful diagrams
- Collaboration
- Integration with CI/CD
- Landscape view (all services on one screen)
Cons:
- Paid (from $12/user/month)
- New tool (may have rough edges)
When to use: Startups willing to invest in architecture documentation
My Recommendations
For startups (1-5 people):
- Mermaid in README.md
- No additional tools
- Cost: $0
For small companies (5-20 people):
- Mermaid for simple diagrams
- PlantUML for complex ones
- Store in
docs/architecture/in Git - Cost: $0
For medium companies (20-100 people):
- PlantUML + C4-PlantUML
- CI/CD auto-generation from code
- Integration testing for synchronization
- Cost: $0 (only developer time)
For enterprises (100+ people):
- Structurizr DSL + Structurizr Cloud
- Or IcePanel for modern UI
- Strict governance and access control
- Cost: $750-1,200/month (for 100 users)
My stack: Mermaid for 80% of cases, PlantUML when I need perfect auto-layout, Structurizr DSL for clients with 50+ services.
Implementation Checklist
Ready to implement C4 in your project? Here's a step-by-step checklist.
Week 1: Foundation
-
Choose a tool
- Small project → Mermaid
- Medium → PlantUML
- Large → Structurizr DSL
-
Create structure in Git
docs/ architecture/ 00-overview.md 01-system-context.md 02-containers.md README.md -
Create Level 1: System Context
- Who are the users?
- What external systems exist?
- What are the main boundaries?
-
Show to the team, gather feedback
Week 2: Detailing
-
Create Level 2: Containers
- List all services/applications
- Show data flows
- Mark critical dependencies
-
Add legend
- Color scheme
- Arrow notation
- Technology icons
-
Document deployment
- Where does it run? (Cloud/on-prem)
- How many instances?
- Which databases?
Week 3: Critical Components
-
Choose 2-3 most complex services
-
Create Level 3: Components for them
- Internal structure
- Interaction between modules
- Patterns (CQRS, Event Sourcing, etc.)
-
Document ADRs (Architecture Decision Records)
- Why this technology?
- What alternatives were considered?
- What are the consequences?
Week 4: Automation
-
Set up auto-generation (if possible)
# Generate from docker-compose.yml python scripts/generate_c4.py -
Add tests for synchronization
def test_all_services_in_c4(): actual = get_services_from_compose() documented = get_services_from_c4() assert actual == documented -
Set up CI/CD
test-architecture: script: - pytest tests/test_architecture_sync.py
Ongoing: Culture
-
Update rule: Changed architecture → update diagram in the same PR
-
Code review: Check that diagrams match code
-
Onboarding: New employee's first task — read C4, ask questions
-
Retro: Every quarter — review relevance of diagrams
Key rule: C4 is not a one-time task, it's a process. Documents live when they're part of development culture.
How C4 Combines with Other Practices
C4 doesn't exist in a vacuum. It's a part of the architecture ecosystem.
C4 + Event Storming
Event Storming — workshop method for discovering business processes and domain events.
How they complement each other:
- Event Storming → identify domains and bounded contexts
- C4 Level 1 → show domains as systems
- C4 Level 2 → show services inside each domain
- Event Storming → define events between services
- C4 dynamic diagrams → show event flows
Example:
After Event Storming we identified:
- Domain: "Orders"
- Events:
OrderCreated,OrderPaid,OrderShipped
In C4:
C4 + ADR (Architecture Decision Records)
ADR — markdown documents with architecture decisions.
How they complement each other:
- C4 — shows "what" (which services exist)
- ADR — explains "why" (why we chose this)
Example:
C4 Container diagram:
ADR-005: Use PostgreSQL for Event Store
# ADR-005: Use PostgreSQL for Event Store
## Status: Accepted
## Context
We need to store events for Event Sourcing.
Considered: EventStoreDB, PostgreSQL, Kafka.
## Decision
Use PostgreSQL with jsonb for events.
## Consequences
- Team already knows PostgreSQL
- No need to learn new tool
- Simpler operations (backup, monitoring)
− Lower performance than specialized EventStoreDB
− Manual implementation of projections
## Alternatives Considered
1. EventStoreDB — specialized, but new tool
2. Kafka — designed for streaming, not storageC4 + Domain-Driven Design (DDD)
DDD — methodology for modeling complex domains.
How they complement each other:
- DDD — defines bounded contexts and aggregates
- C4 — visualizes them
Example:
DDD: Bounded contexts: Orders, Payments, Shipping
C4 Level 2:
DDD: Aggregate Order with entities OrderLine, Discount
C4 Level 3:
C4 + Kubernetes
How they complement each other:
- C4 Level 2 — logical services
- C4 Deployment diagram — how they're deployed in Kubernetes
Example:
Level 2: Containers (logical)
Deployment (Kubernetes)
C4 + Customer Journey Map (CJM)
CJM — customer journey through product.
How they complement each other:
- CJM — business view (what the user does)
- C4 — technical view (which services support this)
Mapping matrix:
| CJM Stage | User Pain Point | C4 Container | C4 Component | Technical Solution | Success Metric |
|---|---|---|---|---|---|
| Discovery | Hard to find courses | Web App + Search Service | SearchEngine, MLRecommender | ML recommendations | CTR >15% |
| Registration | Long, complex form | Auth Service | RegistrationFlow, SocialAuth | OAuth (Google, GitHub) | Conversion >60% |
| Purchase | Concerns about payment security | Payment Service | PaymentGateway, FraudDetection | PCI DSS, 3D Secure | Abandonment <5% |
| Learning | Video buffering | Video Service + CDN | VideoStreaming, AdaptiveBitrate | HLS, CDN edge cache | Start time <2s |
| Completion | No certificate received | Certificate Service | CertificateGenerator, EmailSender | PDF generation, SMTP | Delivery >99.9% |
Example:
CJM: User watches a course (stage: "Learning")
C4 dynamic diagram:
Advanced Techniques
When you've mastered the basics, here are some advanced techniques.
1. Color Coding for Risk Zones
Use colors to highlight critical/risky system components.
Legend:
- 🔵 Blue — standard services
- 🟠 Orange — critical for business (payment)
- 🔴 Red border — contains sensitive data (PII, PCI DSS)
- ⚪ Gray dashed — external services (third-party)
2. Deployment Diagrams for Different Environments
Show how architecture changes across environments.
Production:
Staging:
Development:
3. Dynamic Diagrams for Scenarios
Static diagrams show structure, dynamic ones show behavior.
Scenario: User purchases a course
4. Context Maps for Microservices
Show relationships between team domains (from DDD).
Legend:
- 🟢 Green — Upstream (publishes interface)
- 🟡 Yellow — Downstream (consumes interface)
- 🟠 Orange — Conformist (adapts to any changes)
5. Landscape View for Platforms
When you have 50+ services — group by domain.
My Mistakes with C4 (2019-2025)
I've been using C4 for 6 years. Here are 5 major mistakes I've made.
Mistake #1: "Documentation for Documentation's Sake" (2019)
What I did:
First project with C4. I was excited. Created:
- Level 1: System Context ✅
- Level 2: 15 containers ✅
- Level 3: 47 component diagrams ✅
- Level 4: 128 class diagrams ✅
Total: 190 diagrams.
Result:
- Spent 3 months on documentation
- No one read it
- After 2 months it became outdated
- Team continued to code without C4
Lesson:
Start small. Level 1-2 is enough for 90% of cases. Level 3-4 — only for the most critical/complex components.
Rule: If a diagram hasn't been viewed in 3 months — delete it. Documentation must be living, not a museum.
Mistake #2: "Wrong Tool for the Team" (2020)
What I did:
Implemented Structurizr DSL for a startup of 5 people.
Rationale: "We'll scale to 100 services, need a professional tool!"
Result:
- Spent 2 weeks learning DSL
- Team didn't understand the syntax
- Local Structurizr Lite constantly broke
- Ended up going back to Mermaid
Lesson:
Choose a tool based on current needs, not future ones. Mermaid is enough for 80% of projects.
Rule: Startup (5-20 people) → Mermaid. Company (20-100 people) → PlantUML. Enterprise (100+ people) → Structurizr DSL.
Mistake #3: "Perfect Diagrams, Dead Documentation" (2021)
What I did:
Created beautiful C4 diagrams in PlantUML. Spent a week tweaking colors, icons, layout.
Stored them in a separate architecture repository.
Result:
- Diagrams looked amazing (could show at a conference)
- But developers didn't update them
- After 3 months — 50% of services not documented
- Diagrams were perfect, but useless
Lesson:
Diagrams should live in the same repository as the code. "Architecture as Code" — or death.
Rule: If diagrams are not in Git next to the code — they will die. Always. No exceptions.
Mistake #4: "Forgot About Business" (2022)
What I did:
Created C4 for a client. Detailed Level 2-3, all containers and components.
Showed to the CTO — he was delighted.
Then the CEO asked: "And what value does this bring to customers?"
I couldn't answer.
Result:
Realized I described the technical structure but didn't connect it to business value.
Lesson:
Every service in C4 should have a business justification:
Rule: Level 1 (System Context) should be understandable to the CEO. If not — you did it wrong.
Mistake #5: "Ignored Operations" (2023-2024)
What I did:
Created C4 Level 1-3 for a client. All services, components, data flows.
Launched in production.
At 3 AM received a call: "Everything is down, where's the monitoring?"
Looked at C4 — no observability, no monitoring, no disaster recovery plan.
Result:
C4 showed the "happy path", but not failure scenarios.
Lesson:
Add operational aspects to C4:
Now visible:
- What monitoring exists (Prometheus + Grafana)
- Where logs are stored (Loki)
- How distributed tracing works (Tempo)
- How alerts work (PagerDuty)
Rule: If your C4 doesn't show monitoring/logging/alerting — you're not ready for production.
Conclusion from mistakes: C4 is a tool, not a goal. Use it to solve real problems, not to create perfect diagrams.
Implementation Plan: Week by Week
Ready to implement C4 in your team? Here's a detailed plan.
Week 1: Foundation and Context
Goals:
- Choose a tool
- Create Level 1 (System Context)
- Get team buy-in
Action Plan:
Monday:
- Team meeting: introduce C4 concept (30 minutes)
- Choose tool (Mermaid/PlantUML/Structurizr DSL)
- Create
docs/architecture/structure in repository
Tuesday-Wednesday:
- Create Level 1: System Context
- Identify all users (User, Admin, Support, etc.)
- Identify all external systems (payment systems, APIs, email, etc.)
- Draw boundaries of your system
Thursday:
- Team review of System Context
- Gather feedback and correct
- Add legend and description
Friday:
- Publish System Context to main branch
- Announce in team chat
- Ask everyone to read and comment
Deliverable: 1 System Context diagram understandable to the CEO
Week 2: Containers and Dependencies
Goals:
- Create Level 2 (Containers)
- Document all services and dependencies
- Identify integration points
Action Plan:
Monday:
- List all services/applications (from docker-compose/k8s/etc.)
- Group by layer (frontend, backend, data)
- Identify main data flows
Tuesday-Wednesday:
- Create Level 2: Container diagram
- Add all services
- Draw connections (HTTP, gRPC, message queues, etc.)
- Mark databases and caches
Thursday:
- Add color coding:
- Internal services — blue
- External systems — gray
- Databases with PII — red border
- Add legend
- Document technologies (Node.js, PostgreSQL, Redis, etc.)
Friday:
- Team review
- Correct based on feedback
- Publish to main
Deliverable: 1 Container diagram with all services and dependencies
Week 3: Critical Components
Goals:
- Create Level 3 (Components) for 2-3 most complex services
- Document architecture patterns
- Connect C4 to code
Action Plan:
Monday:
- Team vote: which services are most complex/critical?
- Select 2-3 services for Level 3
- For each service: list main components
Tuesday-Wednesday:
- Create Level 3 diagrams for selected services
- Show internal structure (controllers, services, repositories)
- Document patterns (CQRS, Event Sourcing, Saga, etc.)
- Add links to code (
src/auth-service/README.md → docs/architecture/03-auth-components.md)
Thursday:
- Create ADRs (Architecture Decision Records) for key decisions
- Why PostgreSQL and not MongoDB?
- Why Event Sourcing and not CRUD?
- Why Kafka and not RabbitMQ?
Friday:
- Team review
- Publish to main
- Add C4 links to service READMEs
Deliverable: 2-3 Component diagrams + 3-5 ADRs
Week 4: Automation and Testing
Goals:
- Set up auto-generation (if possible)
- Add tests for synchronization
- Integrate into CI/CD
Action Plan:
Monday-Tuesday:
- Write script for diagram generation from code
- From
docker-compose.yml→ Container diagram - From
kubernetes/*.yaml→ Deployment diagram - From OpenAPI spec → API integrations
- From
Wednesday:
- Write integration tests:
def test_all_services_documented(): actual = get_services_from_docker_compose() documented = get_services_from_c4() assert actual == documented
Thursday:
- Set up CI/CD:
architecture-check: script: - python scripts/generate_c4.py - git diff --exit-code docs/architecture/ - pytest tests/test_architecture_sync.py
Friday:
- Test on real PR (change docker-compose → CI should fail)
- Document update process in README
- Retro: what worked, what didn't?
Deliverable: Automated checks in CI/CD, tests for synchronization
Month 2-3: Embedment and Culture
Ongoing Actions:
Every PR with architecture changes:
- Update C4 in the same PR
- Code review checks diagram relevance
- CI/CD verifies synchronization
Every month:
- Architectural review:
- Are diagrams current?
- Are there new services not in C4?
- Can we remove outdated diagrams?
Every new employee:
- Onboarding task: read C4, ask questions
- After 2 weeks: update C4 (fix inaccuracies found)
Every quarter:
- Architectural retro:
- Did C4 help in the last 3 months?
- What's missing?
- What should be removed?
Key: C4 is not a project, it's a process. Documents live when they're part of development culture, not a one-time task.
Conclusion
C4 Model is a practical framework that actually works. Not just beautiful slides, but a working tool that:
- Reduces onboarding time from 3 weeks to 3 days
- Speeds up architecture decisions by 5x
- Decreases production incidents by 75%
- Returns 1,700% ROI in the first year
Key principles:
- Start simple — Level 1-2 is enough for 90% of cases
- Architecture as Code — diagrams in Git or they'll die
- Automation — generate from code, test in CI/CD
- Culture — documents live when they're part of the process
When C4 works:
✅ Growing team (5+ people)
✅ Microservices/complex system
✅ High onboarding cost
✅ Frequent architecture decisions
✅ Need for transparent architecture
When C4 is overkill:
❌ Landing page on Next.js
❌ Solo developer
❌ Project for 2 weeks
❌ Legacy CRUD with no changes
Next Steps:
- Read official C4 documentation
- Choose a tool (Mermaid for start)
- Create System Context (1 hour)
- Show to team, gather feedback
- Iterate and improve
My experience: I've implemented C4 in 15+ projects. It doesn't work everywhere, but when it does — it radically changes how the team understands the system.
Changelog
Version 1.1 (2025-12-13)
Added:
- TL;DR section for different roles (Developer, Architect, CTO, PM)
- Quick Start "I don't have time to read" section
- Expanded antipatterns from 5 to 10
- Comparison table of methodologies (C4 vs ArchiMate vs UML vs IDEF-0 vs 4+1)
- Detailed CJM→C4 mapping matrix with metrics
- ROI section with real numbers (−87% onboarding, 1,735% ROI)
- "My mistakes with C4" section (2019-2025, 5 major errors)
- Week-by-week implementation plan
- Advanced techniques (color coding, deployment diagrams, dynamic diagrams)
- Practical examples for all 4 C4 levels
Improved:
- Enhanced "Architecture as Code" emphasis throughout article
- Added integration testing examples
- Expanded Tools and Ecosystem section
- Added How C4 Combines with Other Practices section
- More real-world case studies with metrics
Fixed:
- ArchiMate tooling description (clarified free vs paid tools)
- Integration testing example made more concrete
- Quick Start section moved to beginning of article
- Added ADR explanation
Version 1.0 (Initial)
- Basic C4 Model overview
- 4 levels of abstraction
- Basic practical principles
- 5 antipatterns
- Initial comparison with IDEF-0
Related Materials
- Feature-Sliced Design (FSD) — my main favorite for frontend architecture
- Architecture as Hypothesis — philosophical reflections on software architecture
- Slot-Me — booking platform — real project using C4 for architecture documentation
- Official C4 Model documentation — comprehensive guide by Simon Brown
- C4-PlantUML — PlantUML library for C4 diagrams
- Structurizr — official C4 tooling platform


