engineering leadership · architecture · teams
The hardest part happens before the code
After ten years across different companies, projects, and teams, I keep seeing the same pattern: most IT problems are not technological.

Ten years ago, I attended training sessions with Greg Young, Alberto Brandolini, and other experienced practitioners. In the years that followed, I worked across different companies, products, and teams. The technologies changed, but many of the difficult problems looked remarkably similar.
One pattern kept returning: most IT problems are not purely technological.
Writing code is often the straightforward part. The hardest work happens before the code.
It happens while people are trying to understand the problem, agree on language, decide who owns what, and choose which trade-offs they are prepared to carry.
The same problems in different systems
Across startups and enterprises, I have repeatedly seen situations where:
- team members struggle to communicate, and silos and dependencies begin to grow;
- architecture no longer reflects business reality and becomes expensive without producing enough value;
- decisions take longer to make and cost more to implement than expected;
- missing technical leadership makes consequential system changes feel too risky;
- product and engineering start moving in different directions.
The products were different. The people were different. The symptoms were often the same.
I have had the privilege and trust not only to build systems with teams, but also to help people find where delivery is actually getting stuck. Sometimes the constraint is in the code. Often it is in the process, communication, ownership, or an unresolved decision between several reasonable options.
Technology cannot resolve every constraint
Not every difficult system needs:
- microservices or event sourcing;
- AI agents;
- Kubernetes;
- an enterprise architecture programme.
These approaches are not inherently wrong. They are useful when they fit the problem. But applying them before the problem is understood can add another layer of complexity without removing the original constraint.
Sometimes the best solution is a well-built monolith. Sometimes it is a clearer boundary, a smaller decision, or a conversation between people who have been working from different assumptions.
What I want to explore here
This blog is where I will examine the difficult parts of software work that do not fit neatly into an implementation ticket:
- architecture and domain boundaries;
- distributed systems and real-time data;
- modernization without unnecessary rewrites;
- engineering leadership and collaboration across teams;
- where AI helps engineering work, and where it creates new problems;
- lessons from decisions that worked and, just as importantly, those that did not.
The examples will come from real systems and real delivery environments, with identifying details changed where necessary. The goal is not to promote one architecture style. It is to make the problem, the trade-offs, and the decision clearer.
That is the starting point: understand what is actually getting in the way, then choose the technology.