When Not to Use Microservices

Start With a Monolith When...

  • You are a small team (1–8 developers). One codebase is faster to work in.
  • The product is new and the business boundaries are not clear yet. Splitting too early puts walls in the wrong places.
  • You have no DevOps maturity yet: no CI/CD, no container platform, no monitoring.
  • The app is small: a college project, an internal tool, a startup MVP.
  • Your features need strong consistency everywhere (lots of cross-feature transactions).

The Distributed Monolith Trap

The worst outcome is a distributed monolith: the code is split into services, but they still have to be deployed together, share one database, and call each other in long chains. You get all the costs of microservices and none of the benefits.

Distributed monolith (avoid):

  order-service --HTTP--> product-service --HTTP--> pricing-service --HTTP--> tax-service
        \                        |                         |
         +------------------ shared_db (everyone reads every table) ----------+

  - one release needs 4 services deployed together
  - a schema change in shared_db breaks 3 teams

A Sensible Path: Modular Monolith First

  1. Build a modular monolith: one app, but clean packages per business area (product, order, user, payment) that only talk through interfaces.
  2. Keep each module's tables separate, even inside one database.
  3. When a module needs to scale or release on its own, extract it as a service. The interface becomes a REST API.

Tip: Spring Modulith is a Spring project that helps you build and verify a modular monolith. It is a great first step before microservices.

Practice

Exercise: A 3-person startup is building a tiffin-delivery MVP and plans to launch in 2 months. A team member proposes 8 microservices with Kafka and Kubernetes. What would you advise?

Show answer
Start with a single Spring Boot (modular) monolith:
- 3 people cannot run 8 services, a broker and a cluster AND build features.
- The business boundaries will change after launch; splitting now guesses them.
- Use clean modules (menu, order, delivery, user) with interfaces between them,
  one database with separate tables per module, and one CI/CD pipeline.
- Extract a service later when a module has a real need
  (e.g. delivery tracking needs to scale separately).