Diagramming Software Architecture in C4
This page is based off the C4 video on YouTube.
Poor communication slows teams down, so getting information delivered and understood as easily as possible is of vital importance. If the information can be understoord it will result in fewer bugs, faster development, and likely a product that best matches what is actually intended.
Diagramming is a key part of that, the foundation. With a good diagram all team members can move fast in the same direction.
We need to target our stories to different types of audiences. UML will more likely be understood by technical people, but will be difficult for Product owners or business representatives to understand.
One approach is to not think like an architect when creating diagrams, think like a developer.
Above all: The Diagrams must reflect reality.
A common set of abstractions is more important than common notation.
Overview of a software system at a conceptial level is something like this:
NOTE: Container doesn't refer to a Docker container, it is used to refer to a piece of the software, for example and Android application, Database, etc.
A good approach for diagramming is to use the C4 Model. C4 stands for:

Think of diagrams as maps. You zoom into and out of the diagrams to get different levels of detail.
Example 1
Level 1 - System Context Diagram
A "System Context Diagram" basically shows the thing you are working on/building, and the stuff around it such as other systems ot talks to and the people who use the system. So for an internet banking system we start with a single box:

Now we ask: Who is using this system? Add that information:

Where does this system get its information from (external systems):

And where does it interface out to:

This is an example of a system context diagram, it shows:
- What we are working on.
- The environment/context around it.
Level 2 - Container Diagram
As developers and architectures we want more detail, this is where the container diagram is created. The container diagram will show the apps and datastores, and how they are related and run at runtime. We can also build this up piece by piece. This is like zooming into our internet banking system from the level 1 diagram showing the (mostly) separately deployable components:

We start by adding a deployable web application:

This Web App returns a SPA:

But we can also have a mobile app too:

Both the SPA and Mobile App get their data via an API endpoint which is seperately deployable:

We might also need our own database to store app related data (such as login information) that is not contained in the mainframe backing system:

So this is a complete example container diagram showing the various applications and data stores, the technologies they are built with, a little about the responsibilities, and how they connect at runtime.
The components are mostly separately deployable, and the links are mostly interprocess container calls.
Level 3 - Component Diagram
This is a zoom in of a component to show more detail, in this example for the API shown above. We start in a similar way with an empty diagram:

We show who it is used by initially.
To use the apps and API we first need to sign-in, so add this information first:

Once signed in you get a list of accounts, so we assume an Account Summary Controller:

And let's add a way to rest a password too:

In a real world example there would be many more components on the diagram, but this is a good intro on how to show the components that sit inside this example API application.
Crucially, if we were to open the codebase for this project we would expect to find these six items. This diagram needs to reflect the code structure at a high level. There should be a 1-to-1 mapping between the concepts in this diagram and the codebase itself.
Level 4 - Code - Class Diagrams
NOTE: This level is not usually recommended, it's not worth it and can usually be generated automatically from the IDEs using the actual implemented code itself.
This is where UML is useful for documenting and diagramming the lower level aspects:

Level 4 could be useful for complicated components or where something of note should be called out, but is not required for 99% of use cases.
Notation
Notation is important. Here are some tips:
- Put Titles on pictures. Type of diagram and scope.
- Layout is important. Keep things clean. Use Post-It notes to help visually with this if other tools or a whiteboard are not available - but don't deliver this as things can fall off!
- Visual Consistency. Try to use consistent notation, colour coding, shapes and element positioning across diagrams.
- Take care with using Acronyms. Consider the target audience, for example using MVC with developers is fine, but consider business level terminology, acronyms and system codenames which can catch out new joiners.
- Elements. Start with simple boxes containing the element name, type, technology (if appropriate) and description/responsibilities. The following are the only 4 types of elements expected on a diagram:

- The system context diagram shows: People and Software System elements.
- The container diagram shows: People, Software Systems and container elements.
- The component diagram potentially shows all four element types.
- A Short description can also be added to the elements. This isn't usual in architecture diagrams, but this can help understanding, as shown in the following diagram, but must be kept short:

- Lines give structure and glue the elements together. Prefer uni-directional lines. Prefer Thing A calls B, or A bepends on B. Make sure text on the arrow is consistent with the direction. For Bi-directional relationships show the intent, for example:

Becomes:

- Avoid using the word "Uses".
- Use two arrows if the intents are different:

- Beware of hiding the true story, for example with a hub and spoke diagram, for example this doesn't show the flow clearly:

Where as this is much cleaner:

- Add words to make the intent explicit, Read the diagrams out aloud to see if they make sense!
- There are no hard and fast rules - focus on making the diagrams as clear and explicit as possible!
- Add a Key/Legend to explain shapes, line styles, colours, borders, acronyms, etc. even if it seems obvious:

- Use shapes and colour to complement a diagram that already makes sense. Watch out for colourblindness and monochrome printers! If you remove the shapes and colours it should still make sense. Adding these should just make it clearer.
- Use icons to supplement text, not replace it. Use to complement information, as with colours.
All this is to make the diagram readable and able to stand on their own. New joiners with limited context should be able to make sense of them. Any narrative should complement the diagram.
See the simple checklist at C4Model.com
Key Rule
Abstractions first, notation second.