Featured in DevOps

Adin Scannell talks about gVisor - a container runtime that implements the Linux kernel API in userspace using Go. He talks about the architectural challenges associated with userspace kernels, the positive and negative experiences with Go as an implementation language, and finally, how to ensure API coverage and compatibility.

The C4 Model for Software Architecture

Key Takeaways

The creation of software diagrams has been scaled back as a result of the shift to agile methodologies. When diagrams are created, they are often confusing and unclear.

The C4 model consists of a hierarchical set of software architecture diagrams for context, containers, components, and code.

The hierarchy of the C4 diagrams provides different levels of abstraction, each of which is relevant to a different audience.

Avoid ambiguity in your diagrams by including a sufficient amount of text as well as a key/legend for the notation you use.

Software architecture diagrams are a fantastic way to communicate how you are planning to build a software system (up-front design) or how an existing software system works (retrospective documentation, knowledge sharing, and learning).

However, it's very likely that the majority of the software architecture diagrams you've seen are a confused mess of boxes and lines. An unfortunate and unintended side effect of the Manifesto for Agile Software Development is that many teams have stopped or scaled back their diagramming and documentation efforts, including the use of UML.

These same teams now tend to rely on ad hoc diagrams that they draw on a whiteboard or put together using general-purpose diagramming tools such as Microsoft Visio. Ionut Balosin last year wrote "The Art of Crafting Architectural Diagrams", which describes a number of common problems with doing this, related to incomprehensible notations and unclear semantics.

(Click on the image to enlarge it)

Ambiguous software architecture diagrams lead to misunderstanding, which can slow a good team down. In our industry, we really should be striving to create better software architecture diagrams. After years of building software myself and working with teams around the world, I've created something I call the "C4 model". C4 stands for context, containers, components, and code — a set of hierarchical diagrams that you can use to describe your software architecture at different zoom levels, each useful for different audiences. Think of it as Google Maps for your code.

(Click on the image to enlarge it)

To create these maps of your code, you first need a common set of abstractions to create a ubiquitous language to use to describe the static structure of a software system. The C4 model considers the static structures of a software system in terms of containers (applications, data stores, microservices, etc.), components, and code. It also considers the people who use the software systems that we build.

(Click on the image to enlarge it)

Level 1: System context diagram

Level 1, a system context diagram, shows the software system you are building and how it fits into the world in terms of the people who use it and the other software systems it interacts with. Here is an example of a system context diagram that describes an Internet banking system that you may be building:

(Click on the image to enlarge it)

Personal customers of the bank use the Internet banking system to view information about their bank accounts and to make payments. The Internet banking system uses the bank's existing mainframe banking system to do this, and uses the bank's existing e-mail system to send e-mail to customers. Colour coding in the diagram indicates which software systems already exist (the grey boxes) and those to be built (blue).

Level 2: Container diagram

Level 2, a container diagram, zooms into the software system, and shows the containers (applications, data stores, microservices, etc.) that make up that software system. Technology decisions are also a key part of this diagram. Below is a sample container diagram for the Internet banking system. It shows that the Internet banking system (the dashed box) is made up of five containers: a server-side web application, a client-side single-page application, a mobile app, a server-side API application, and a database.

(Click on the image to enlarge it)

The web application is a Java/Spring MVC web application that simply serves static content (HTML, CSS, and JavaScript), including the content that makes up the single-page application. The single-page application is an Angular application that runs in the customer's web browser, providing all of the Internet banking features. Alternatively, customers can use the cross-platform Xamarin mobile app to access a subset of the Internet banking functionality. Both the single-page application and mobile app use a JSON/HTTPS API, which another Java/Spring MVC application running on the server side provides. The API application gets user information from the database (a relational-database schema). The API application also communicates with the existing mainframe banking system, using a proprietary XML/HTTPS interface, to get information about bank accounts or make transactions. The API application also uses the existing e-mail system if it needs to send e-mail to customers.

Level 3: Component diagram

Level 3, a component diagram, zooms into an individual container to show the components inside it. These components should map to real abstractions (e.g., a grouping of code) in your codebase. Here is a sample component diagram for the fictional Internet banking system that shows some (rather than all) of the components within the API application.

(Click on the image to enlarge it)

Two Spring MVC Rest Controllers provide access points for the JSON/HTTPS API, with each controller subsequently using other components to access data from the database and mainframe banking system.

Level 4: Code

Finally, if you really want or need to, you can zoom into an individual component to show how that component is implemented. This is a sample (and partial) UML class diagram for the fictional Internet banking system that, showing the code elements (interfaces and classes) that make up the MainframeBankingSystemFacade component.

(Click on the image to enlarge it)

It shows that the component is made up of a number of classes, with the implementation details directly reflecting the code. I wouldn't necessarily recommend creating diagrams at this level of detail, especially when you can obtain them on demand from most IDEs.

Notation

The C4 model doesn't prescribe any particular notation, and what you see in these sample diagrams is a simple notation that works well on whiteboards, paper, sticky notes, index cards, and a variety of diagramming tools. You can use UML as your notation, too, with the appropriate use of packages, components, and stereotypes. Regardless of the notation that you use, I would recommend that every element includes a name, the element type (i.e., "Person", "Software System", "Container", or "Component"), a technology choice (if appropriate), and some descriptive text. It might seem unusual to include so much text in a diagram, but this additional text removes much of ambiguity typically seen on software architecture diagrams.

Make sure that you have a key/legend to describe any notation that you're using, even if it's obvious to you. This should cover colours, shapes, acronyms, line styles, borders, sizing, etc. Your notation should ideally remain consistent across each level of detail. Here is the diagram key/legend for the container diagram shown previously.

(Click on the image to enlarge it)

Finally, don't forget about the diagram title, which should appear on every diagram to unambiguously describe each diagram’s type and scope (e.g., "System context diagram for Internet banking system").

More information

The C4 model is a simple way to communicate software architecture at different levels of abstraction, so that you can tell different stories to different audiences. It's also a way to introduce (often, reintroduce) some rigour and lightweight modelling to software development teams. See c4model.com for more information about the C4 model, as well as supplementary diagrams (runtime and deployment), examples, a notation checklist, FAQs, videos from conference talks, and tooling options.

About the Author

Simon Brown is an independent consultant specialising in software architecture, and the author of "Software Architecture for Developers" (a developer-friendly guide to software architecture, technical leadership and the balance with agility). He is also the creator of the C4 software architecture model, which is a simple approach to creating maps of your code. Simon is a regular speaker at international software development conferences and travels the world to help organisations visualise and document their software architecture.