The C4 model for visualising software architecture

Diagramming vs modelling

As an industry, we’ve tended to prefer diagramming over modelling, primarily because the barrier to entry is relatively low, and it’s seen as a much simpler task.
When you’re diagramming, you’re typically creating one or more separate diagrams, often with an ad hoc notation, using tools (e.g. Microsoft Visio or a whiteboard)
that don’t understand anything about the semantics of your diagrams. The domain language of diagramming tools is really just boxes and lines, so you can’t ask them questions such as “what dependencies does component X have?”.
Additionally, reusing diagram elements across diagrams is usually done by duplication (i.e. copying and pasting), thereby putting the responsibility on you to keep diagrams in sync when you rename such elements.
It’s worth noting here that the C4 model can be used irrespective of whether you are diagramming or modelling, but there are some interesting opportunities when you progress from diagramming to modelling.

With modelling, you’re building up a non-visual model of something (e.g. the software architecture of a software system), and then creating different views (e.g. diagrams) on top of that model.
This requires a little more rigour, but the result is a single definition of all elements and the relationships between them.
This, in turn, allows modelling tools to understand the semantics of what you’re trying to do, and provide additional intelligence on top of the model.
It also allows modelling tools to provide alternative visualisations, often automatically.

One of the frequently asked questions (above) is about diagramming large and complex software systems.
Once you start to have more than ~20 elements (plus the relationships between them) on a diagram, the resulting diagram starts to become cluttered very quickly.
For example, image 1 (below) is a component diagram for a single container.

One approach to dealing with this is to not show all of the components on a single diagram, and instead create multiple diagrams, one per “slice” through the container (image 2, below).
This approach can certainly help, but it’s worth asking whether the resulting diagrams are useful.
Are you going to use them and, if so, what are you going to use them for?
Although the System Context and Container diagrams are very useful, Component diagrams for large software systems often have less value because they are harder to keep up to date, and you might find that very few people look at them anyway, especially if they are not included in documentation or presentations.

A large and cluttered diagram

Once you have more than ~20 elements on a diagram, the diagram starts to become cluttered very quickly.

A smaller diagram showing an individual slice

Creating multiple diagrams, one per “slice”, can help, although the resulting diagrams tend to be very simple and increase the effort needed to keep them up to date.

An alternative visualisation

Rather than creating a diagram, you can use alternative visualisations instead. This visualisation shows the dependencies between components inside a container.

An alternative visualisation

And this alternative visualisation shows all of the elements and relationships in the model, filtered to show a subset of the model.

Often, the diagrams themselves aren’t the end-goal, with teams using the diagrams to answer other questions that they have, such as, “what dependencies does component X have?”.
If this is the case, building a model will allow you to answer such questions, without the additional effort of creating a diagram.
In other words, once you have a model, you can visualise it in a number of different ways (images 3 and 4, above), helping to answer the real questions that you are seeking to answer.
Diagrams certainly are a fantastic way to communicate software architecture, but other visualisations can sometimes help answer the real underlying questions that you might have.