Practicing systems thinking to become a better developer
Regularly practicing systems thinking is worthwhile for your career, but also because it gives a valuable lens to explore and better understand the world we live in. Everything is connected, and by understanding the systems around us, we can identify leverage points where we can make effective changes.
This text assumes some familiarity with the fundamental concepts of systems thinking, but should still be worthwhile for anyone curious about improving their craft and creating impactful software projects. If you're curious to learn more, I can highly recommend the following books:
- Fundamental Theory: Thinking in Systems: A Primer
- Why and how this matters for the IT world: Learning Systems Thinking: Essential Non-Linear Skills and Practices for Software Professionals
These books are some of the most influential and inspiring books I've read on the topic so far. After practicing systems thinking for several years and exploring many resources, they both strike a good balance between being approachable while introducing in-depth topics for further exploration.
Software: one part of a larger socio-technical system
As software systems evolve and change over time, both the complexity of the code itself and the interconnections between different parts of the system tend to increase. A technical change like this will also have social and cultural implications. This is because a similar increase in complexity and interconnections also happens for the people, teams and organizations involved in developing, maintaining and using the software.
For developers, working in this kind of environment requires a quite different perspective and approach compared to working with one isolated software module. The software itself needs to adapt to changing requirements and conditions, but also the needs and preferences of the people and organizations using the software. We could make this easier, for example by making the software flexible and ready for change by designing the software as a collection of composable modules.
But that's just how we could structure the software itself. There are also other expectations on both on the software and the team developing it:
- The software adapts to the changing expectations of the world around us, including new regulation.
- The software needs to work well for the people and organizations who use it, while also being accessible and performant.
- Both the software and the team around it can handle changes within the organization, given that people come and go, while some software often can be used in production for years or decades.
- Ideally, the software should be delivered as quickly and smoothly as possible, making effective use of the resources, skills and time available in the (often cross-functional) team of product-owners, designers, and developers.
- Regular updates and improvements to the software, patching security issues and keeping a high development velocity.
Combining all these perspectives, it becomes clear that professional software development requires more skills than programming: It's also about the surrounding system of people, processes and communication involved to make the software achieve the desired outcomes.
In other words, the software itself is part of a larger socio-technical system which surrounds - and supports it. In some ways, software is quite similar to a living organism, interacting with its environment and gradually evolving. Both are systems of systems that would not exist without their environment, and they are both constantly shaping their environment just like it shapes them.
Working with systems of systems
There are many factors that determine how well a given piece of software, and the teams and processes around it work together.
In this kind of environment, it's hard to find all solutions by only applying logic and thinking step by step, using an approach commonly referred to as linear thinking. While it's very useful when solving specific problems with clear conditions and boundaries, it's much harder (if even possible) to use linear thinking to solve problems in the complex socio-technical systems we often work with. Of course, there are still pure software and programming problems, but also many other kinds of work that needs to be done which can't be solved in a clear, linear way. The software is often just one piece in a much larger puzzle, where the ability to deliver high quality products and services relies on the successful collaboration involving many people.
It's also worth pointing out that this applies for all other software your project interacts with, each surrounded by its own socio-technical system. Even upstream and downstream dependencies - both internal or external - often need to be taken into account. How is your software project influenced by the risks with supply chain attacks?
Let me rephrase that - how is your organization contributing to the software you depend on, to make sure it's well-funded and well-maintained?
The main point is that all these socio-technical systems can be viewed both separately and as one large interconnected system. Given all their interconnections and varying conditions, how do we make all parts work well both on their own and together? There is no easy answer, but there are practices you can use in order to ask better questions and find where you can make changes. Systems thinking is one such practice.
How systems thinking can help developers
With this complex environment surrounding most projects, thinking about yet another layer of interactions can easily get overwhelming if you are not used to it. But it will get easier with practice.
Before we explore how systems thinking can help, it's important to note that this is just one approach among others. This is not the ultimate way to view the world in every situation. However, by practicing systems thinking for some years, I've found it to be very useful when you want to get a better understanding - and ask better questions.
Systems thinking is useful because it makes it easier and more enjoyable to work in this kind of environment. But like most skills worth learning, it takes practice, reflection and patience. To support your learning, it's helpful to create an intentional culture of curiosity, prototyping and willingness to not just improve your software development skills, but also your communication and collaboration skills. Ultimately, systems thinking can also help you grow as a person by increasing your self awareness and making reflective learning a habit.
However, if I only get to choose one of the main benefits of systems thinking for developers, I have to say how it teaches you how to identify leverage points in systems.
Using systems thinking to identify leverage points
Sometimes, changing the software or the processes around its development is not enough. This is when we need to map out the surrounding systems in greater detail, exploring how the software interacts with people, organizations and even society and the living planet.
With a gradually more nuanced understanding of the system and its interconnections, we can start exploring leverage points. These are places where we can make changes to affect the behaviour of the system. Just like when you try to move a stone and by using a lever to be able to move heavier objects with less effort, you can use leverage points in systems to find places where you can create effective change.
This is one of the most important skills to learn as a software developer, where one of your primary career objectives should be to get better at identifying the most high impact work you can do at any given moment. This will help you set priorities, and keep a healthy balance between proactive (long term improvements) and reactive work (short term bug fixing). How? By saying no to less important tasks and by separating potential future ideas from the actual high, mid and low impact work.
Working with systems of systems, you can learn to identify leverage points where you can make changes to subsystems to affect the outcome of the larger system. For example, identifying the backend service where you could invest your time and energy to get the biggest improvement to the overall user experience. Or even identifying ways to improve the communication/collaboration within your team to improve your iteration speed while creating better conditions for the team members to grow professionally.
This might not seem like system development if you just started working as a professional developer, but perspectives like these get more important as you gain more responsibility within your team and organization. Sometimes, its more impactful to really get to know your team and find how you can improve your collaboration, rather than purely focusing on completing tasks. Though this is usually not a problem if the organization has a strong learning culture where people genuinely want to improve both their craft, and their processes.
Beyond development: systems thinking as a core skill for the 21st century
I'm actively exploring and practicing systems thinking since several years back, and the more I learn, the more convinced I become that systems thinking is a fundamental skill for anyone working with software. Not only for developers or architects, but also for people working with design, product and even the underlying business design.
Business design, you might think - how is this related to the software? In my view, the business design shapes the purpose of the organization and determines how features or improvements are prioritized, and which values and worldview that get baked into the software. These things shape the product or service itself, which in turn shapes how the product or service interacts with the surrounding world, in both positive and negative ways.
If your goal is to increase the positive impact while reducing the negative impact that your software has in the world, you need to understand at which layer to make effective changes. To achieve some types of real-world changes, you need to change your business design, consisting of the purpose, networks, governance, ownership, finance. I highly recommend Doughnut design for business if you're curious. This is in stark contrast to if you try to get different results while you keep using the same structures that caused the problems in the first place. Every organization is not yet ready for this type of exploration, though more and more are.
Some organizations that have successful used systems thinking and identified leverage points are: Libro.fm for buying audiobooks while supporting bookshops, Subvert.fm for buying music while supporting artists or Fairphone for repairable phones, modular hardware and software longevity. All of these organizations have found real-world problems where old, obsolete business models caused negative externalities for people and planet, and are now working towards fixing them. The leverage points they used were partly in the software layer, but mainly in the business design.
By practicing systems thinking and learning to map out systems and how they are interconnected, you can more easily identify opportunities for improvements. This can also help you mitigate risks, increase resilience and improve maintainability of not just the software, but also the people and organization around it.
Practicing systems thinking
Here are some ideas for how to start learning, and most importantly, practicing - systems thinking:
- Explore theory - Read books and research papers, watch talks or listen to podcasts. Be an active learner and write notes about things you find interesting and useful. Write down your questions about things you don't understand, and later on follow up when you find good answers. Also, writing is thinking and helps you both with organizing your thoughts, and improves your communication because now you have a structure of words, concepts and ideas that you can share with others.
- Use systems thinking in practice - View the world (and your projects) as systems. Try to understand how they work, and how they are interconnected. Apply the tools and methods from systems thinking, and with time you start to find things like new connections that you wouldn't have thought about before, or even leverage points where you could make the most impactful changes.
- Experiment and learn - Approach problems with curiosity and view them as learning opportunities. Most often, you can experiment and learn how to find better solutions. Remember that everything is a process and the best solutions often take several iterations.
- Reflect on your learning - No matter the outcome of the experiments, write down what went well, what didn't and what can be improved in the next iteration. Maybe you missed a critical detail of how a system works, causing your solution to not work as intended. Maybe something happened in the social aspect of software development that affected your outcome. Also make sure to highlight the things that did go well and prioritising new iterations and experiments instead of overanalyzing.
- Iterate - Repetition is key. Start small and make it a habit.
The developer as a learning system
As for my personal journey, the last few years have been highly rewarding and taught me a lot about systems thinking for software development. Sometimes helping me identify and take care of high impact work and make meaningful contributions. Sometimes finding and fixing a potential problem before it causes too much trouble. Sometimes failing to do so and instead gaining experience and learning valuable lessons. Most importantly though, the core practice of regular experimentation, reflection and learning is probably the most valuable skill of all.
A reflective and systematic approach to learning changes the perspective so the only true failures are when things don't go as you planned and you also failed to learn anything from the experience. In my view, this is the difference between feeling content with passively gaining more experience of various situations, compared to actively improving your proficiency by following your curiosity and deliberately practicing your skills and craft.
Given that everything changes constantly, skills like continuous learning and the ability to both understand systems and find leverage points to make effective interventions will only become more important. Especially for software developers.
To wrap up, I'd like to repeat what I wrote in the beginning:
Regularly practicing systems thinking is worthwhile for your career, but also because it gives a valuable lens to explore and better understand the world we live in. Everything is connected, and by understanding the systems around us, we can identify leverage points where we can make effective changes.
Let's move fast and fix things 🌱