Simple architecture often beats trendy
How the urge to use the right stack and draw beautiful diagrams quietly breaks projects that could have been running calmly for years.
When a team faces a blank page and a generous budget, the urge is to draw something impressive. A data bus, an orchestrator, queues, events, a cluster, a separate service per entity.
That is a normal human impulse. And it is almost always a bad start.
Why "the right stack" is not the same as "the right solution"
Technology choices do not exist in a vacuum. They live inside:
- the size and maturity of the team;
- the budget and the timeline;
- the real volume of data, not the imagined one;
- the pace of change in the business;
- the company's appetite for maintaining complexity.
Microservices, Kafka, separate stores per domain - all of that works. It works under specific conditions. When the conditions are not there, the "modern" stack becomes a heavy tax that gets paid every day.
What usually happens to over-architected systems
After 6 to 12 months in production, the symptoms are the same:
- only the original author still understands how everything is connected;
- any new feature has to touch several services;
- the time required for simple changes grows non-linearly;
- failures become hard to localise;
- onboarding a new engineer turns into a separate project.
Meanwhile, the actual business problems the system was built for could have been solved on a much simpler footprint.
What "simple architecture" means in practice
It does not mean "monolith and full stop". It means:
- start from the smallest viable set of components;
- add complexity only when there is a measurable constraint forcing it;
- prefer well-understood technology over fashionable;
- keep data and logic close to each other until there is a real reason to separate them;
- ask "what falls over if we delete this layer?" - and if the answer is "nothing", delete it.
Simple architecture often looks boring on a diagram. It is also explainable to a new engineer in half an hour, and it survives three changes of team.
When complexity is justified
Complexity is worth introducing when:
- there is real load that the simple version actually cannot handle;
- different parts of the system evolve at very different speeds and slow each other down;
- different teams need to ship independently and are stepping on each other today;
- there are concrete reliability or isolation requirements that cannot be worked around.
In all of these cases, complexity is the answer to a problem you can point at. Not "because that is what everyone is doing".
A simple engineering filter
Before adding a new layer, service, queue, or framework, I ask three questions:
- What concrete problem does this solve right now?
- How much does it cost in operation?
- What do we lose if we do not add it?
If the first answer is unclear, this is decoration, not engineering. And in a project that has to live longer than the team's enthusiasm, decoration almost always costs more than it looks.