Engineering Notes
Why Businext uses a modular monolith
A practical analysis of why a modular monolith was the right choice for Businext ERP: lower operational complexity, simpler deployments, direct integration between domains, and faster evolution for a small engineering team.
Tradeoff Analysis
2026-03-09
10 min read
The real discussion is not monolith vs microservices
In enterprise architecture, the debate between monoliths and microservices is often framed as a maturity path.
Start with a monolith. Then evolve to microservices.
In practice this narrative is overly simplistic.
The correct decision depends on:
- how stable domain boundaries are
- how expensive distributed coordination would be
- how much operational complexity the team can support
ERP platforms amplify these questions because many domains share a single operational truth.
The nature of ERP systems
ERP platforms combine several business domains:
finance
inventory
sales
reconciliation
reporting
administrative operations
These domains are distinct but rarely independent.
A sales operation may affect inventory.
Inventory movements may affect accounting.
Financial reconciliation may depend on events produced by other modules.
Many flows therefore require coordinated state transitions and reliable auditability.
Why teams often move too early
Microservices promise real benefits:
- independent deployments
- clearer ownership
- isolated scaling
- domain decoupling
However, when services are extracted before domain boundaries mature, systems often develop new problems:
- services requiring internal knowledge of each other
- fragile distributed transactions
- increasing observability costs
- time spent operating infrastructure instead of improving the domain
For growing enterprise platforms, this can mean too much complexity too early.
The modular monolith approach
Businext was designed as a modular monolith.
All domains live inside the same backend but maintain explicit boundaries.
Each business area runs as a module:
CRM
HRM
SRM
PMS
EMS
RMS
IMS
SMS
AMS
EIS
Each module is implemented as a FastAPI application mounted inside the same backend.
This architecture provides:
- direct integration between domains
- simpler transactional consistency
- single deployment boundary
- lower operational complexity
These properties are especially valuable for small teams.
The problem this approach avoids
A modular monolith avoids a common issue in prematurely distributed systems: moving coupling from code to the network.
When domains still require coordinated decisions, separating services often replaces internal dependencies with:
- API calls
- message queues
- distributed transactions
- eventual consistency
This increases operational complexity without necessarily improving domain clarity.
When microservices become useful
Microservices become more valuable once several conditions exist:
- domains with proven independence
- teams capable of owning services end-to-end
- different scaling requirements
- operational maturity in monitoring and failure handling
At that point service boundaries can reduce risk rather than increase it.
Three useful questions
Before extracting a service, three questions are often more useful than generic checklists:
- Can this domain evolve without reinterpreting another domain’s rules?
- Can the team confidently operate distributed failures?
- Does extraction reduce coupling or simply move it to APIs?
If the coupling remains the same, the service likely isn’t ready to exist independently.
A pragmatic approach
Instead of asking “when should we adopt microservices?”, a better question is:
Which domain boundaries are strong enough that distribution will actually reduce risk?
For many internal enterprise platforms the most practical path is:
- start as a modular monolith
- enforce domain ownership from the beginning
- observe where coordination pain appears
- extract services only when boundaries are proven
This keeps architecture aligned with business reality rather than architectural trends.
Businext was not designed as microservices, but as a modular monolith where each business domain evolves inside a FastAPI application mounted within the same backend.