When Should You Split a Monolith? Strategies and Principles for Microservice Migration
This article explains why and when to break a monolithic application into microservices, outlines the business and technical signals that trigger splitting, presents guiding principles, functional and non‑functional strategies, and risk‑mitigation practices to ensure a smooth, sustainable migration.
Background
Microservices have become mainstream in recent years, and many companies are considering a microservice architecture. With the rise of Docker containers and automated operations, managing microservices has become easier, providing a strong development opportunity.
Purpose of Splitting
Before diving into how to split services, it is essential to understand the purpose of splitting so that the original goal is not forgotten during the process.
Problems of a Monolith
The monolithic approach initially offers simplicity: code and projects are centrally managed, debugging is straightforward, and a single repository reduces operational overhead. However, as functionality grows and team size expands, several issues emerge:
Database connection limits become a bottleneck for scaling application servers.
Development cost rises and efficiency drops due to duplicated effort, code conflicts, and tight coupling between features.
Build and deployment times increase dramatically, making frequent releases impractical.
These problems can be addressed by splitting the monolith into microservices.
When to Split
Business scale: after the product has been market‑validated and is in the growth stage, the scale of the business justifies splitting.
Team size: typically when the development team reaches around one hundred people.
Technical readiness: availability of domain‑driven design, service registry, configuration center, logging, continuous delivery, monitoring, distributed scheduling, CAP theory, distributed tracing, API gateway, etc.
Talent: architects and developers experienced with microservice implementation.
R&D efficiency: a noticeable decline in development efficiency signals the need to split.
Splitting Principles
High cohesion, low coupling : each service should own a single responsibility and delegate other responsibilities to other services.
Closed‑Component Principle (CCP) : changes to a service should not require modifications in other services.
Service autonomy and interface isolation : minimize strong dependencies between services and expose functionality through well‑defined interfaces.
Continuous evolution : start with a few services and gradually increase granularity as the domain understanding deepens.
Avoid impacting product iteration : split non‑core services first (e.g., SMS) and prioritize splitting services that are heavily depended upon.
Extensible service interfaces : design interfaces with version‑tolerant data structures (e.g., wrapper objects) to avoid breaking changes.
Avoid circular and bidirectional dependencies : such dependencies indicate unclear boundaries.
Stage‑wise merging : periodically review and merge services when boundaries become blurred.
Splitting Strategy
Functional Dimension
Use Domain‑Driven Design (DDD) to define bounded contexts and map each context to a microservice. The four steps are:
Identify domain entities and value objects.
Determine aggregate roots and form aggregates.
Define bounded contexts based on business semantics.
Map each bounded context to a microservice, considering non‑functional factors.
Example: an e‑commerce transaction flow can be divided into bounded contexts such as order, payment, inventory, etc., each becoming a separate service.
Non‑Functional Dimension
Scalability : separate components with high load or performance requirements (e.g., flash‑sale queue) and apply read‑write separation.
Reusability : extract common cross‑cutting concerns (authentication, rate limiting, logging) into shared services like an API gateway.
High performance : isolate performance‑critical modules to prevent them from affecting other services.
High availability : split core services from non‑core ones and ensure redundancy.
Security : place highly sensitive services in isolated zones (e.g., DMZ) to meet stricter security requirements.
Heterogeneity : implement services in different programming languages when required by the domain.
These dimensions can be combined freely according to the actual scenario.
Risk Management During Splitting
Before starting, ensure the team has sufficient experience with the microservice stack or conduct thorough technical proof‑of‑concepts. Common pitfalls include insufficient resources, operational complexity, inter‑service call failures, retries, timeouts, and distributed transactions.
Continuously validate the splitting plan, be ready to adjust as business evolves, and treat splitting as an iterative process rather than a one‑time optimal solution.
Conclusion
Splitting granularity is not “the finer, the better”; it must align with business complexity, team size, and the “bow‑arrow principle” and “three musketeers principle”. A balanced, evolving approach, combined with proper governance and tooling, leads to a sustainable microservice architecture.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
