The Case for Building Fewer Things, Better
Hatched by tfc
Apr 22, 2026
9 min read
6 views
78%
The Hidden Cost of Premature Splitting
The software industry has spent years telling itself a seductive story: when systems become hard to manage, split them apart. Break the platform into services. Break the architecture into layers. Break the codebase into repositories. Break complexity into smaller and smaller pieces until it feels tractable.
But what if the real problem is not that systems are too large? What if the problem is that we keep splitting them before we have learned what should stay together?
That question sits at the center of two ideas that are often discussed separately: the rise of modular monoliths and the emergence of opinionated platform building blocks for data systems. One is about application structure. The other is about infrastructure composition. Yet both point to the same uncomfortable insight: in software, the hardest thing is not decomposing a system. It is deciding which boundaries deserve to exist at all.
A system that is broken apart too early does not become simpler. It often becomes more ceremonial, more brittle, and more expensive to change. Teams spend their energy coordinating boundaries instead of solving problems. The irony is that fragmentation, which is supposed to create clarity, frequently creates a new kind of chaos: a system whose parts are individually understandable but collectively ungovernable.
Why Structure Is Not the Same as Simplicity
There is a common assumption in engineering culture that smaller pieces automatically mean better architecture. Smaller components are easier to reason about, easier to test, and easier to assign to teams. That is true, up to a point. But size is not the same thing as simplicity. A system can be physically small and logically fragmented. It can be distributed across services, pipelines, accounts, and repositories, while still being conceptually tangled.
A modular monolith challenges the reflex to distribute everything. It says: keep the application in one deployable unit if the real coupling is still strong, but organize it into clear internal modules with explicit contracts. That gives you a paradoxical combination: cohesion without premature distribution. You get most of the benefits people seek from microservices, such as separation of concerns and local reasoning, without paying the orchestration tax too early.
The same logic appears in data platforms. Instead of asking engineers to assemble every piece of the platform from raw cloud primitives, an opinionated framework provides building blocks for familiar abstractions such as a data lake. The platform is still customizable, but the starting point is shaped around how data systems actually work in practice. This matters because most teams do not need infinite freedom. They need a system that helps them make the right choices faster.
Here is the deeper pattern: good architecture is not the maximum possible decoupling. It is the right amount of coupling, made visible and intentional.
The goal is not to remove boundaries everywhere. The goal is to place boundaries only where they create more leverage than friction.
This reframes architecture from a purity test into a judgment problem. You are not trying to prove that your system is elegant in the abstract. You are trying to make it easier for real people to build, operate, and change under real constraints.
The Boundary Problem: When Abstraction Helps and When It Hides Reality
Every system design choice is also a theory about future change. When you split a codebase into modules, or a platform into reusable building blocks, you are making a bet about which parts will evolve independently and which parts should move together. If the bet is right, the system becomes more adaptable. If the bet is wrong, you create false independence, which is often worse than no independence at all.
This is why opinionated frameworks are so interesting. Opinionated sounds limiting, but in practice it can be liberating. A framework that encodes common abstractions, such as a data lake, is saying: here is the shape of the problem as it is usually encountered, here is a reasonable default, and here are the extension points where your business logic belongs. That frees engineers from rebuilding boilerplate and from making low-value decisions repeatedly.
A modular monolith does something similar at the application level. Instead of exposing every internal concern as a network boundary, it encourages a disciplined internal architecture. The modules are not decorative folders. They are enforceable conceptual units, each with a purpose, dependencies, and a limited surface area. The system remains one organism, but it behaves as if it has organs.
This is a subtle but crucial distinction. A network boundary is not a module. A deployment boundary is not a domain boundary. A cloud service is not automatically an architectural insight. Too often, teams confuse observable separation with meaningful separation. They assume that if parts can be independently deployed or independently provisioned, they must also be independently conceptualized. But the world does not always cooperate.
Think of a kitchen. You could separate the knives, pots, spices, cutting boards, and stove into different rooms because each object is distinct. But unless the cooking process itself benefits from that separation, you are just making the chef walk farther. Better design does not mean isolating everything. It means arranging tools so that the workflow becomes natural.
In that sense, both modular monoliths and platform frameworks are anti-chaos tools. They push back against the idea that freedom is the absence of structure. In reality, freedom comes from the right structure, at the right level.
The Real Tradeoff Is Not Monolith versus Distributed, It Is Learning Speed versus Coordination Cost
The old debate often frames architecture as a binary choice: monolith or microservices, hand-built platform or framework, flexibility or standardization. That framing misses the deeper economic question. Every architectural choice changes two things: how fast a team can learn, and how much coordination it must pay.
A distributed architecture can reduce local coupling, but it usually increases coordination across boundaries. More services means more APIs, more contracts, more testing layers, more observability needs, more deployment concerns, and more failure modes. A modular monolith, by contrast, keeps coordination costs lower while preserving internal structure. It is a way of staying integrated while still learning where the seams are.
The same is true in platform engineering. A framework like DSF, which offers common data abstractions and CI/CD building blocks, can drastically reduce setup time and operational drift. Teams stop reinventing the pipeline for every project. They can focus on use case and business logic rather than the mechanics of infrastructure assembly. But the framework’s value is not just speed. It is that it captures a learning curve once, centrally, so every new team does not pay the same tuition.
This suggests a powerful mental model: architecture should minimize repeated decisions that do not teach you anything new.
That is the difference between productive standardization and oppressive uniformity. Productive standardization removes friction from known problems. Oppressive uniformity removes discretion from genuinely novel problems. The best systems do both things at once: they standardize the boring parts, and they allow customization where the business actually differs.
A good modular monolith does this internally. The modules establish a stable shape, but each module can evolve according to its own logic. A good data platform framework does this infrastructurally. The building blocks establish a standard skeleton, but the business logic remains adaptable. In both cases, the system is not rigid. It is constrained in the right places and open in the right places.
That is an important philosophical correction. Many teams chase flexibility by making everything customizable. In practice, unlimited flexibility often means no one knows what the system is supposed to be. Better systems do the opposite: they define a strong default path and make deviations deliberate.
A Practical Framework for Choosing Boundaries
If these ideas are more than stylistic preferences, they should lead to a usable decision framework. The question is not whether to modularize or standardize. The question is where to draw the line so that the system remains easy to evolve without becoming hard to govern.
Here is a simple way to think about it.
1. Start with the shape of the problem, not the shape of the org chart
Do not split a system just because multiple teams exist. Split it when the business domain truly contains separate modes of change. If two parts of the system change together, they belong together more than they belong apart.
2. Prefer internal boundaries before external ones
Before turning a capability into a service, ask whether a strong module is enough. Before turning a platform capability into bespoke infrastructure, ask whether a reusable framework can express it. Internal boundaries are cheaper to change than external ones.
3. Standardize the repetitive, customize the differentiating
A data lake blueprint, a CI/CD pipeline, a module structure, a repository convention, these are often great candidates for standardization. Customer-specific logic, domain rules, and unusual operational needs should remain customizable. Do not standardize what makes the business unique.
4. Measure coordination cost, not just deployment independence
Independent deployment looks attractive, but it is only one dimension of health. Watch for contract churn, integration complexity, observability burden, and team time spent on cross-boundary negotiations. If those costs are rising faster than the value of separation, the boundary may be too early.
5. Treat architecture as a reversible decision, not a destiny
A modular monolith can become distributed later if the seams prove real. A platform framework can be extended or replaced if the defaults stop fitting. The point is not to freeze architecture forever. The point is to avoid locking in a boundary before the system has earned it.
Mature engineering does not begin by asking, “How do we split this?” It begins by asking, “What must remain together for now, and what can safely be separated later?”
This is a more disciplined posture than either purist monolith thinking or reflexive microservice thinking. It honors the fact that systems are not solved by ideology. They are solved by incremental judgment, informed by feedback.
Key Takeaways
- Simplicity is not the same as fragmentation. A smaller, more distributed system can still be harder to understand than a larger integrated one.
- Use internal modules before external services. If strong boundaries exist conceptually but not operationally, a modular monolith may be the right first move.
- Standardize the common path, not the business logic. Frameworks are most valuable when they remove repetitive setup while preserving room for differentiated use cases.
- Optimize for learning speed and coordination cost. Good architecture reduces the amount of repeated decision making and cross-team negotiation.
- Assume boundaries are provisional. The best systems make it easy to revisit a split once real evidence shows that the seam is justified.
Building Fewer Things Is Often the More Ambitious Choice
The deepest connection between modular monoliths and opinionated platform frameworks is not technical. It is managerial and epistemic. Both are ways of admitting that teams do better when they are not forced to invent structure from scratch every time. Both recognize that too much freedom becomes entropy, and too much decomposition becomes overhead.
The real craft lies in designing systems that preserve enough unity to stay coherent while introducing enough modularity to stay adaptable. That is a harder problem than simply splitting things apart. It requires you to understand what the system is, how it changes, and where the true seams live.
In that sense, the most advanced architecture is not the one with the most pieces. It is the one with the fewest unnecessary pieces, the clearest boundaries, and the highest ratio of useful structure to accidental complexity.
The next time a system feels difficult, the first question should not be how to break it into more parts. It should be this: what if the hardest part of the design is not decomposition, but restraint?
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣