Architecture
When a Modular Monolith Is the Right Choice
A practical way to decide whether a modular monolith is a better fit than distributed services.
Software architecture should follow the constraints of the business, the product and the team — not the current trend.
Start with the actual problem
Microservices can provide independent deployment and scaling, but they also introduce network boundaries, distributed observability and more operational overhead.
Before splitting a system, ask:
- Do teams genuinely need independent deployments?
- Do parts of the system have very different scaling requirements?
- Are the domain boundaries already understood?
- Can the organisation support the added operational complexity?
Keep boundaries without adding a network
A modular monolith can keep business areas separate inside one deployable application. Clear modules, explicit interfaces and automated tests preserve those boundaries without requiring distributed infrastructure.
final readonly class CreateInvoice
{
public function __construct(
private InvoiceRepository $invoices,
) {}
public function execute(CreateInvoiceCommand $command): Invoice
{
$invoice = Invoice::create($command->customerId, $command->lines);
$this->invoices->save($invoice);
return $invoice;
}
}
A useful default
Start with the simplest architecture that protects the important boundaries. Move to distributed services when production evidence and organisational needs justify the cost — not before.
