Profile    Mohammed Shiroz Status   Loading  
Logo
Share This
Back to blog
Filter by:
Tags
//Article title

Monolith vs Microservices: What Most Teams Actually Need

About Post

Here's an unpopular opinion that I'll defend for the rest of this article: most teams that move to microservices don't have a scaling problem. They have an organisation problem, a messy codebase, or a conference talk they enjoyed. Microservices fix exactly one of those, and only sometimes.

That doesn't make microservices wrong. It makes them expensive, and you should know what you're buying. So let's compare the two honestly, then look at the option I think most teams actually need: the modular monolith.

The real difference is not the number of repos

A monolith is one deployable application. A microservice architecture is many small applications, each owning its own data, talking to each other over the network.

That last part is the whole story. Inside a monolith, "get the tenant's balance" is a function call. It takes nanoseconds, it can't time out, and if it throws, you get a stack trace. Between services, the same thing is an HTTP request or a message on a queue. It can be slow. It can fail. It can succeed while the response gets lost. The other service can be mid-deploy, running a different version, or down.

Every function call you turn into a network call becomes a distributed systems problem. That's the price, and it's paid on every feature, forever.

Side by side

MonolithMicroservices
DeployingOne pipeline, one artifactMany pipelines, version compatibility between services
Data consistencyDatabase transactions just workNo cross-service transactions; sagas, outbox pattern, eventual consistency
DebuggingOne log, one stack traceDistributed tracing needed to follow one request
Local developmentRun one appRun many services, or mock them
Refactoring across boundariesYour IDE renames itA versioned API change and a coordinated rollout
ScalingScale the whole app (often perfectly fine)Scale only the hot parts
Team independenceTeams share one codebase and release trainTeams deploy on their own schedule
Technology choiceOne main stackEach service can use what fits

Look at where microservices win: independent scaling, independent teams, independent technology. Those are real benefits, and they matter a lot when you have many teams stepping on each other in one codebase. They matter very little when you have one team of five.

"But our monolith is a mess"

This is the most common reason I hear, and the most dangerous one. If the code is tangled, with every part reaching into every other part's tables, splitting it into services doesn't remove the tangle. It moves it onto the network. You get what people call a distributed monolith: all the coupling of the old system, plus latency, partial failures and five deploy pipelines that must release together.

A mess is a boundaries problem. The fix is drawing boundaries, and you can do that without a single network call.

The modular monolith

A modular monolith is one deployable app, split inside into modules with clear ownership and rules about how they talk. In Laravel, it can be as plain as folders:

app/
  Modules/
    Leasing/        contracts, renewals
    Billing/        invoices, payments
    Maintenance/    requests, work orders
  Shared/           money, dates, common value objects

Each module has its own models, services, events and often its own service provider. The rules that make it work:

  • Modules talk through a public surface, such as a service class or events, never by querying each other's tables or models directly.
  • Each table has one owning module. Billing writes invoices. Leasing asks Billing.
  • Cross-module side effects use events. Leasing dispatches ContractSigned; Billing listens and creates the first invoice.

Rules nobody checks become suggestions, so enforce them. If you use Pest, architecture tests make it a failing build instead of a code review argument:

arch('leasing does not touch billing internals')
    ->expect('App\Modules\Leasing')
    ->not->toUse('App\Modules\Billing\Models');

Packages like nwidart/laravel-modules give you more structure if you want it, but plain folders and a few arch tests get you most of the value.

The quiet superpower: if one module ever truly needs to become a service, it's already behind a clean interface. You swap the in-process call for an HTTP client, and nothing else in the app has to know. Extracting a service from a modular monolith is surgery. Extracting one from a tangled monolith is an archaeology dig.

When splitting really is the answer

I'd consider pulling something out into its own service when at least one of these is true and hurting:

  • Very different scaling needs. A PDF or image processing workload that eats CPU while the rest of the app is mostly idle.
  • Very different reliability needs. Something that must keep working when the main app is down, or must not take it down when it fails.
  • A team that genuinely needs its own release cycle, because coordinating with everyone else has become the bottleneck.
  • A different runtime does the job much better, like a Node or Python service for a specific library or AI workload.

Notice what's not on the list: "it's more modern", "the code is messy", "we might need to scale one day".

And the honest middle ground: in many Laravel apps, queues and separate worker processes already give you most of the scaling benefit. Heavy jobs run on their own worker servers, scaled independently, while the code stays in one repository with one deploy.

My default: start with a modular monolith, enforce the boundaries, and extract a service only when you can name the specific pain it removes. Splitting is easy to do later. Merging services back together almost never happens.

The checklist before you split

  • Can you name the module boundaries today, in your current code?
  • Does each table have exactly one owner?
  • Do you have the tracing, monitoring and deploy automation to run several services?
  • Is the pain you're solving about scale, reliability or teams, and not just tidiness?

If the first two answers are no, microservices will make things worse. If all four are yes, you probably already know which service to extract first.

Where does your team sit right now: happy monolith, modular monolith, or a set of services you sometimes wish were one app?

Comments (0)
Leave your review

Thanks for your valuable comments. Your comments has been updated and appreciate your getting in touch...

01. About Shiroz

Mohammed Shiroz

Hi, I'm Mohammed Shiroz, a software engineer and AI enthusiast from Sri Lanka who turns ideas into intelligent, real-world solutions. With over 9 years of hands-on experience, I currently lead real estate ERP development at Kate Group, a...

03.My Projects

04. Categories

Ready To order Your Project ?

Get in Touch
Close