Abhishek Singh logoAbhishek Singh
JourneyWorkBlogContact
Book a call
Abhishek Singh logoAbhishek Singh

Full stack and AI solutions engineer. I build software and automation that make businesses run faster, and write about the engineering behind it.

Explore
HomeJourneyWorkBlogContact
Writing
AI DevelopmentBackend EngineeringAI-Assisted DevelopmentAll posts
Get in touch

Have a project or a problem worth solving? Tell me what is slowing your business down and I will tell you honestly how I would fix it.

Contact me→
© 2026 Abhishek Singh. All rights reserved.
Available for new projects
Back to Blog

Software Architecture & Scaling

Split a Monolith Only When You Actually Need To

microservices
monolith
modular monolith
software architecture
strangler pattern
scaling
system design
distributed systems
Aug 10, 2026
12 min read
1 views
Split a Monolith Only When You Actually Need To

Microservices are a solution to a problem you may not have

Somewhere along the way, microservices became the default answer to "how should we build this," and monoliths became something to apologize for. That is backwards. Microservices solve real problems, but they are a solution to organizational and scaling problems, not a starting point. Splitting a monolith into microservices before you have those problems does not make your system more professional, it makes it a distributed system, with all the network calls, data consistency puzzles, and operational overhead that entails, and none of the benefits you were promised. Most teams that split early spend the next year missing the simple monolith they gave up. This guide takes the honest position: keep your monolith until it genuinely hurts, and this is how to know when that is and what to do about it.

To be clear, this is not anti-microservices. It is about sequencing. The right question is never "monolith or microservices," it is "what problem am I solving, and is splitting the cheapest way to solve it." We will look at what splitting actually costs, the modular monolith that gives you most of the benefits with far less pain, the real signals that you have outgrown a single deployable, and a safe, incremental way to extract services when the time comes. The goal is to spend your complexity budget only where it buys something.

The hidden cost of splitting too early

Split Monolith Microservices Cost

The diagram above shows what you actually sign up for when you move to microservices. Each service tends to own its own database, which multiplies what you have to run, back up, and keep consistent. Every call that used to be an in-process function is now a network call, which adds latency and brand-new failure modes, a request can now fail halfway. Debugging a single user action means tracing it across several services, so you need distributed tracing just to see what happened.

You need an API gateway and the platform to run it, infrastructure a monolith never required. And you are now on call for many services instead of one. For a small team, that operational weight is not a footnote, it is most of your week. None of this makes microservices wrong, but all of it is cost you pay up front, before you have earned any of the upside.

The modular monolith is usually the smarter default

Split Monolith Modular

Here is the option most teams skip, and it is usually the right one. A modular monolith, shown above, is a single deployable application with strict internal boundaries. Each module owns its own domain and data, and modules talk to each other only through defined interfaces, never by reaching into each other's tables.

You get clean separation, clear ownership, and code that is easy to reason about, but you deploy one thing, debug in one process, and run one database. Crucially, a well-built modular monolith is also the ideal launchpad if you ever do split, because those module boundaries become your future service boundaries.

The discipline lives in the structure and the interfaces. Keep modules from depending on each other's internals.

src/
  auth/        # owns users, sessions;   exposes AuthModule
  orders/      # owns carts, orders;     exposes OrdersModule
  billing/     # owns invoices, charges; exposes BillingModule
  catalog/     # owns products, stock;   exposes CatalogModule
  shared/      # truly shared primitives only
# Orders talks to Billing ONLY through its public interface,
# never by importing Billing's models or querying billing tables.
class OrdersService:
    def __init__(self, billing: BillingModule):
        self.billing = billing

    def place_order(self, cart):
        order = self.repo.create(cart)
        self.billing.charge(order.id, order.total)   # a clean, swappable seam
        return order

That one rule, cross-module communication through interfaces only, is what keeps a monolith from rotting into a "big ball of mud," and it is what makes a later split a refactor rather than a rewrite.

When you actually need to split

Split Monolith Crossover

So when is splitting into microservices worth it? The chart above captures the intuition: a monolith is cheaper until a crossover point, after which its costs climb and microservices, despite high fixed overhead, pull ahead. You are near that crossover when you see concrete, recurring pain, not hypothetical future scale. The honest signals are: multiple teams are stepping on each other in one codebase and deploys have become a coordination bottleneck; one part of the system needs to scale independently of the rest, for very different load; different components genuinely need different runtimes or resource profiles; or one flaky component keeps taking down everything and you need fault isolation. Notice that every one of these is an organizational or scaling problem that a single deployable makes worse.

If you cannot point to one of them happening now, you are not at the crossover yet, and splitting will cost you more than it returns.

Just as important is what is not a reason to split: it is not because microservices are modern, not because a big company you admire uses them, and not because your monolith feels messy, since a messy monolith usually just needs the module boundaries from the previous section, not a network between its parts.

How to split without regret

Split Monolith Strangler

When you do have a real reason, do not attempt a big-bang rewrite, which is how these projects fail. Use the strangler pattern, shown above. Put a router in front of your system, then extract one service at a time, starting with the single most painful piece. Route just that path to the new service and leave everything else in the monolith, running and untouched.

# The router sends one path to the new service and everything else to the monolith.
location /orders/ {
    proxy_pass http://orders-service;      # newly extracted, scales on its own
}
location / {
    proxy_pass http://monolith;            # everything else, unchanged
}

Because you built clean module boundaries earlier, the extraction is mostly mechanical: the new Orders service exposes the same interface the OrdersModule did, takes ownership of the orders data, and the monolith calls it over the network instead of in process. Ship that, watch it in production, and only then decide whether to extract the next piece. Repeat until the services you actually need exist, and stop there. You are allowed to end up with a monolith plus two services, that is often the correct architecture, not a failure to finish.

Decide with your problems, not the trends

The whole decision comes down to a simple discipline: split into microservices only to solve a problem you can name today, and reach for the cheapest tool that solves it. Start with a well-structured modular monolith, because it gives you clean boundaries and clear ownership without the distributed tax, and it doubles as the perfect starting point for a later split. Watch for the real signals, team contention, independent scaling, fault isolation, and when one genuinely appears, extract one service at a time with the strangler pattern, guided by the boundaries you already drew. Microservices are a powerful tool once you have earned them. Until then, the boring monolith is quietly winning, and that is a good place to be.


Articles Worth Reading

  • If you're considering a distributed architecture, read about our microservices mistake before you commit.

  • If you're just getting started, here's how to set up Claude Code and ship your first task.

  • Learn how to turn those repeat prompts into reusable Claude Code skills that your whole team can run the same way every time.

  • If missed calls are costing you customers, an AI voice agent that answers every call can pick up the slack.

  • Turning a flaky prototype into production-ready AI agents takes idempotency, validation, guardrails, and full observability.

  • Learn how simple demand forecasting can help you cut food waste and stock closer to real demand.


Useful Links

  • Martin Fowler, MonolithFirst

  • Martin Fowler, the Microservice Premium

  • Martin Fowler, the Strangler Fig application

  • Shopify Engineering, deconstructing the monolith with a modular approach

Table of Contents

  • Microservices are a solution to a problem you may not have
  • The hidden cost of splitting too early
  • The modular monolith is usually the smarter default
  • When you actually need to split
  • How to split without regret
  • Decide with your problems, not the trends
  • Articles Worth Reading
  • Useful Links

Frequently Asked Questions

Let's build

Have a project worth building?

If this maps to a problem in your business, tell me about it. I will tell you honestly whether software or AI can fix it, and how I would build it.

Book a free call →See my work

Continue Reading

We Thought Microservices Would Scale Us Faster. Instead, It Slowed the Team and Burned Money
Software Architecture & Scaling7 min read

We Thought Microservices Would Scale Us Faster. Instead, It Slowed the Team and Burned Money

Microservices sounded like the right move. Everyone was doing it. Six months later, delivery slowed, costs went up, and simple bugs took days to trace. Here’s what actually went wrong and how we fixed it without blowing up the product.

Mar 06, 202626 views