existence
← All posts
EngineeringAugust 2026 · 5 min read

Systems thinking: fixing the shape, not the instance.

The most expensive bugs we ever fixed were the same small decision made six times. Here is the habit that changed how we build: understand the whole system, then optimise it end to end.

S
SiyabongaAuthor
XLinkedIn
Systems thinking

The most expensive bugs we have ever fixed were never really bugs. They were the same small decision, made six times, in six apps, by people who could not see the other five. Nothing was broken in isolation. Everything was slightly wrong together. Learning to see that pattern, and to fix the whole shape of it rather than one instance, is the single habit that has changed how we build at Existence. We call it systems thinking, and it is less a technique than a way of refusing to be fooled by the part in front of you.

The part looks fine. The system does not.

It is easy to optimise a part. You can make one screen faster, one function cleaner, one app a little more polished, and every one of those wins is real when you measure it on its own. The trouble is that software is not a pile of parts. It is a set of relationships, and a change that looks like an improvement locally can quietly make the whole worse. A cache that speeds up one request can starve another. A clever shortcut in one app becomes the thing a new engineer copies into the next four. The local number goes up; the global one goes down; and because nobody was measuring the whole, the cost hides in plain sight for months.

We felt this most sharply in the years when every app owned its own copy of everything. Six apps meant six auth flows, six theming systems, six slightly different answers to the same question. Each was defensible on its own. Together they were a tax we paid every single time we wanted to change our minds.

Optimising a part you do not understand in a system you have not mapped is just moving the problem somewhere you are not looking.

Understanding before optimising

Systems thinking starts with a boring discipline: understand how the thing actually works before you touch it. Not the diagram of how it is supposed to work, but the real path a request takes, the real order in which state changes, the real reason a value is where it is. Most of the time the map is more valuable than the fix. Once you can see the whole flow, the right change is often smaller and further upstream than the one you set out to make. You stop patching symptoms at the edges and start moving the one piece in the middle that everything else depends on.

This is why our core framework, e_core, is really an argument about where things belong. If more than one app needs a capability, that capability is not an app detail. It is a system property, and it should be understood, owned, and improved in one place. Auth, theming, notifications, localisation: each one moved from six private implementations to a single shared package, not because sharing code is tidy, but because a capability you can only reason about in one place is a capability you can actually optimise end to end.

One more capability, understood once

The most recent proof of this arrived quietly. We added a new shared capability to the core: a single layer that any Existence app can switch on through one import, with the details of the underlying provider hidden behind a clean interface. Because it lives behind an abstraction, the concrete implementation is a decision we can change later without rewriting a single screen. Because it ships turned off by default, an app opts in deliberately rather than inheriting behaviour it never asked for. And because it was understood as a system property from the start, the lifecycle, the failure states, and the on and off switch were designed once, tested once, and handed to the whole suite at the same time.

The contrast with how we would have done this two years ago is the entire point. The old way was to wire it into one app, get it working, and let the pattern spread by copy and paste until it was quietly living in all of them, each copy ageing at its own pace. The systems way is to ask, before writing anything, what the correct behaviour is for the whole suite, and to build that.

6apps, one core
1place to change your mind
0screens rewritten to swap it

What the habit looks like in practice

Systems thinking is not a meeting or a template. It is a set of questions we have learned to ask before we reach for the keyboard:

  • Where does this really live? If the answer is “in several apps at once,” the honest fix is upstream, not in the file you happen to have open.
  • What does this change touch that I cannot see? The relationships matter more than the node. A local win that pushes cost onto a part you are not measuring is not a win.
  • Am I fixing the instance or the shape? Fixing one occurrence of a problem guarantees you will fix it again. Fixing the shape means it stops happening.
  • What is the feedback loop? A system you cannot observe end to end is one you are optimising blind. Make the whole path measurable before you tune any piece of it.

Optimising the whole, not the piece

The payoff is not abstract. When a capability is understood in one place, improving it improves everything at once. Handle a denied permission more gracefully, and every app is more graceful the same afternoon. Change the provider behind an interface, and no screen notices. The work compounds instead of scattering. That is the quiet promise of thinking in systems: effort spent understanding the whole is not overhead, it is the thing that makes every later change cheap.

None of this means grand rewrites or big-bang architecture. Most of it is small: pausing to map before patching, asking where a thing belongs, resisting the pull of the local fix that feels good and ages badly. We get it wrong plenty. But the direction is clear, and it is the same one that took us from six copies of everything to a core we can actually reason about. Understand how it works. Find the piece the whole depends on. Optimise end to end, or do not call it optimising at all.

S
SiyabongaWriting for Existence

Notes, as they happen.

One email when we publish. No digest, no drip, just the post.