Avdi Grimm describes how the book Vehicles illustrates how simple parts can compose a very complex system.
Another example is Conway’s Game of Life: a nice organized grid, uniform time steps, and four tiny rules. These simple pieces combine to make all kinds of wild patterns, and even look alive!
These systems are complex: hard to predict; forces interact to produce surprising behavior.
They are not complicated: they do not have a bunch of different parts, nor a lot of little details.
In software, a monolith is complicated. It has many interconnected parts, each full of details. Conditionals abound, forming intricate rules that may surprise us when we read them.
But we can read them.
As Avdi points out, microservices are different. Break that monolith into tiny pieces, and each piece can be simple. Put those pieces together in a distributed system, and … crap. Distributed systems are inherently complex. Interactions can’t be predicted. Surprising behaviors occur.
Complicated programs can be understood, it’s just a lot to hold in your head. Build a good enough model of the relevant pieces, and you can reason out the consequences pf change.
Complex systems can’t be fully understood. We can notice patterns, but we can’t guarantee what will happen when we change it.
Be careful in your aim for simplicity: don’t trade a little complication for a lot of complexity.