Over the last decade, microservices have become the default answer to many architectural challenges. Teams often move from monolithic applications to dozens or hundreds of independently deployable services in pursuit of scalability, agility, and team autonomy.
Sometimes this is the right decision.
But sometimes the operational cost of microservices outweighs their benefits.
After working with large-scale financial systems, I've become increasingly interested in a different architectural approach: the Component-Based Monolith.
Many systems start life as a modular monolith.
A single codebase contains multiple business components such as:
Accounts
Balances
FX
Payments
Reporting
Each component owns a specific business capability while sharing a common deployment unit.
This approach aligns well with the Common Closure Principle (CCP):
Components that change together should be packaged together.
As systems grow, pressure often emerges to split these components into independent microservices.
The reasoning is usually sound:
Independent release cycles
Separate ownership
Smaller deployment units
Reduced coupling between business domains
These goals align with principles such as:
REP (Reuse/Release Equivalence Principle)
CRP (Common Reuse Principle)
On paper, everything looks better.
In practice, things can become more complicated.
Imagine a system split into 50 microservices.
Each service has:
Its own repository
Its own CI/CD pipeline
Its own deployment process
Its own monitoring configuration
Its own release management
Now imagine all 50 services depend on:
Spring Boot
Logging frameworks
Security libraries
Database drivers
Internal shared libraries
A security update arrives.
A framework upgrade is required.
A dependency reaches end-of-life.
Suddenly every service needs attention.
Instead of one upgrade effort, the organization now has 50 upgrade efforts.
The architecture has unintentionally created a large number of reasons to change.
This is where another important principle enters the discussion.
The Stable Dependencies Principle (SDP) states:
Depend in the direction of stability.
The practical interpretation is simple:
The dependency structure of your system has a direct impact on your maintenance costs.
When many services share the same dependencies, every dependency upgrade creates work across the entire platform.
The more distributed the architecture becomes, the more expensive these renovations become.
This cost is often underestimated during initial architecture discussions.
Teams focus heavily on deployment independence.
They spend less time calculating long-term maintenance overhead.
A Component-Based Monolith attempts to combine the strengths of both worlds.
The system remains a single deployable application, often managed through a monorepo, but business capabilities are structured as independent components with strict boundaries.
For example:
/accounts
/balances
/fx
/payments
/reporting
Each component:
Owns its business logic
Exposes clear interfaces
Maintains strong boundaries
Can be developed independently
At the same time:
Shared dependencies are upgraded once
CI/CD pipelines are simplified
Operational complexity is reduced
Renovation work becomes significantly cheaper
The architecture preserves modularity without introducing the full operational burden of distributed systems.
One of the most expensive activities in software engineering is not feature development.
It is maintenance.
Security upgrades.
Framework migrations.
Dependency updates.
Platform modernization.
Operational support.
Over a ten-year period, these costs often exceed the cost of building the original system.
This means architecture decisions should not be evaluated solely on deployment flexibility.
They should also be evaluated on long-term maintenance economics.
Microservices are not bad.
Monoliths are not old-fashioned.
Component-Based Monoliths are not a silver bullet.
Every architecture exists within a specific context.
The real question is not:
"Should we use microservices?"
The real question is:
"Which architecture minimizes the total cost of change over the next ten years?"
For many organizations, the answer may not be hundreds of services.
It may be a well-designed component-based monolith with clear boundaries, independent teams, and dramatically lower operational overhead.
At ALM Solutions, we believe architecture should be evaluated not by trends, but by outcomes.
The best architecture is rarely the most fashionable one.
It is the one that continues to deliver value long after the initial implementation is complete.