Start free trial
Searching...
SoBrief
English
EnglishEnglish
EspañolSpanish
简体中文Chinese
繁體中文Chinese (Traditional)
FrançaisFrench
DeutschGerman
日本語Japanese
PortuguêsPortuguese
ItalianoItalian
한국어Korean
РусскийRussian
NederlandsDutch
العربيةArabic
PolskiPolish
हिन्दीHindi
Tiếng ViệtVietnamese
SvenskaSwedish
ΕλληνικάGreek
TürkçeTurkish
ไทยThai
ČeštinaCzech
RomânăRomanian
MagyarHungarian
УкраїнськаUkrainian
Bahasa IndonesiaIndonesian
DanskDanish
SuomiFinnish
БългарскиBulgarian
עבריתHebrew
NorskNorwegian
HrvatskiCroatian
CatalàCatalan
SlovenčinaSlovak
LietuviųLithuanian
SlovenščinaSlovenian
СрпскиSerbian
EestiEstonian
LatviešuLatvian
فارسیPersian
മലയാളംMalayalam
தமிழ்Tamil
اردوUrdu
Monolith to Microservices

Monolith to Microservices

Evolutionary Patterns to Transform Your Monolith
by Sam Newman 2019 255 pages
4.29
1k+ ratings
Listen
Try Full Access for 3 Days
Unlock listening & more!
Continue

Key Takeaways

1. Microservices are a strategic choice, not a default goal.

Microservices are not the goal. You don’t “win” by having microservices.

Outcome-driven adoption. Adopting a microservice architecture should be a conscious decision, driven by specific business outcomes you aim to achieve that your current monolithic system cannot. Without a clear understanding of these goals, organizations risk falling into a "cargo cult" mentality, adopting microservices simply because others like Netflix do, without understanding the underlying rationale or the significant investment required. This often leads to wasted effort and disillusionment when expected benefits don't materialize.

Key questions. Before embarking on a microservice migration, ask three critical questions:

  • What are you hoping to achieve? (e.g., improved team autonomy, faster time to market, better scalability, enhanced robustness, ability to use new technology)
  • Have you considered alternatives? (e.g., horizontal scaling of monolith, modular monolith, better automation, refactoring existing code)
  • How will you know if the transition is working? (e.g., defining measurable outcomes and feedback mechanisms)

Avoid blind pursuit. Many teams adopt microservices without truly understanding the "why," leading to significant investment without clear direction. Focusing on desired outcomes, rather than the architecture itself, ensures that the effort is aligned with business value and provides a framework for evaluating success. This critical thinking helps avoid the sunk cost fallacy and allows for course correction if the chosen path proves unsuitable.

2. Independent deployability and business domain alignment are core principles.

If there is only one thing you take out of this book, it should be this: ensure you embrace the concept of independent deployability of your microservices.

Loose coupling is key. Microservices are defined as independently deployable services modeled around a business domain. Independent deployability means a service can be changed and deployed to production without affecting or requiring changes to any other service. This necessitates loose coupling between services, achieved through explicit, well-defined, and stable contracts, which in turn guides how service boundaries are drawn.

Business domain focus. Services should encapsulate business capabilities, not technical layers. Traditional three-tiered architectures, often mirroring organizational structures (Conway's Law), spread business functionality across layers, making changes expensive. Microservices aim for high cohesion of business functionality, meaning related business logic and data reside within a single service, minimizing cross-service changes.

  • Traditional: UI, Business Logic, Data layers owned by different teams.
  • Microservices: A "slice" of UI, logic, and data encapsulated within a single service, aligned to a business domain (e.g., a Customer service).

Information hiding. The principle of information hiding is crucial for stable service interfaces. Services should expose as little as possible, hiding internal implementation details (like database schemas) that are prone to change. This allows internal modifications without impacting consumers, ensuring independent deployability and reducing ripple effects across the system.

3. Services must own their data; avoid shared databases at all costs.

Don’t share databases, unless you really have to. And even then do everything you can to avoid it.

Encapsulate data. A fundamental tenet of microservices is that each service should encapsulate its own data storage and retrieval mechanisms. This means databases are hidden inside the service boundary, and if one service needs data from another, it must request it via the owning service's well-defined interface, not by directly accessing its database. This enforces information hiding and loose coupling.

Problems with shared databases:

  • Implementation coupling: Changes to a shared schema can break multiple services, hindering independent deployability.
  • Unclear ownership: It becomes ambiguous who "controls" the data and its associated business logic, leading to inconsistent behavior and difficulty in making changes.
  • Lack of cohesion: Business logic manipulating the data becomes spread across services, making it hard to implement and maintain state machines for domain entities.

Coping mechanisms. If immediate database decomposition is impossible, temporary coping patterns can help:

  • Database View: Present a limited, read-only projection of the underlying schema to consumers, hiding sensitive details.
  • Database Wrapping Service: Place a thin service wrapper in front of a shared database, forcing all access through an API, which can then evolve independently of the underlying schema.
    These are temporary measures; the ultimate goal remains full data ownership by each service.

4. Incremental migration is the safest path to microservices.

If you do a big-bang rewrite, the only thing you’re guaranteed of is a big bang.

Reduce risk. A "big-bang" rewrite of a monolithic system into microservices is highly risky and almost always leads to failure. Instead, an incremental approach, chipping away at the monolith one piece at a time, is strongly advised. This strategy allows teams to learn from each small step, limit the impact of mistakes, and adapt their approach as new insights emerge.

Learn and adapt. Each small migration step provides valuable feedback on the efficacy of the chosen approach, the performance of new services, and the operational challenges of a distributed system. This iterative learning process is crucial for refining the migration strategy and building confidence.

  • Small steps: Break down large tasks into manageable, reversible changes.
  • Quick wins: Prioritize extracting functionality that is easier to move and delivers immediate value.
  • Production counts: A migration step is not complete until the new service is deployed to production and actively used, as most critical lessons are learned there.

Cost of change. Incremental changes reduce the cost of mistakes. Most decisions in a microservice transition are "reversible" (Type 2 decisions), meaning they can be easily undone. By making small, reversible changes, teams can experiment, learn, and correct course without significant repercussions, avoiding the "sunk cost fallacy" that often plagues large, irreversible projects.

5. The Strangler Fig pattern is a powerful tool for gradual system transformation.

The idea is that the old and the new can coexist, giving the new system time to grow and potentially entirely replace the old system.

Coexistence and redirection. The Strangler Fig pattern involves wrapping a new microservice architecture around an existing monolith. Calls to functionality that has been migrated to microservices are rerouted, while other calls continue to hit the monolith. This allows the new system to grow incrementally, supported by the old, until it can eventually replace it entirely.

How it works:

  1. Identify functionality: Pinpoint parts of the monolith to migrate.
  2. Implement new service: Build the new functionality as a microservice.
  3. Reroute calls: Use a proxy (e.g., HTTP reverse proxy) to direct traffic from the monolith to the new service. This separates deployment from release, allowing the new service to be deployed and tested in production before it's actively used.

Benefits and considerations:

  • Low disruption: Allows migration without altering the monolith, ideal for black-box systems or heavily contended codebases.
  • Reversibility: Easy to switch traffic back to the monolith if issues arise.
  • Incremental rollout: Supports migrating small slices of functionality, even partial features, to reduce risk.
  • Protocol transformation: Proxies can also transform communication protocols (e.g., SOAP to gRPC), though this adds complexity to the proxy layer.
  • UI Composition: UI elements can be composed from both old and new systems (e.g., page composition, widget composition, micro frontends), providing a visible path for migration.

This pattern is often the first choice for migration due to its flexibility and low-risk approach to incremental change, allowing continuous feature delivery alongside architectural transformation.

6. Database decomposition is complex and requires dedicated strategies.

Splitting a database apart is far from a simple endeavor, however. We need to consider issues of data synchronization during transition, logical versus physical schema decomposition, transactional integrity, joins, latency, and more.

Logical vs. physical separation. Database decomposition primarily aims for logical separation, where each service owns its schema, even if multiple schemas reside on the same physical database engine. Physical separation (separate engines) offers additional benefits like improved robustness and resource isolation but is a secondary concern after achieving logical independence. The choice depends on balancing benefits against the cost and complexity of managing multiple database instances.

Sequencing the split. Deciding whether to split the database or the code first is a critical choice:

  • Database first: Splits schemas while keeping code monolithic. Helps identify performance/transactional issues early but offers few short-term benefits.
  • Code first: Extracts service code, leaving a shared database. Provides early independent deployability but risks leaving a permanently shared database.
  • Both at once: Highest risk, generally discouraged due to increased complexity.

Key decomposition patterns:

  • Split Table: Divides a single table across multiple service boundaries, often requiring careful ownership decisions for individual columns.
  • Move Foreign-Key Relationship to Code: Replaces database-enforced foreign-key constraints with application-level logic, introducing challenges in data consistency and increased latency for join operations.
  • Multischema Storage: Allows a new service to manage its own data in a separate schema while still accessing legacy data from the monolith.

These patterns highlight that database decomposition is rarely a clean cut and often involves trade-offs in consistency, performance, and complexity.

7. Embrace Sagas for distributed processes, and avoid two-phase commits.

In my experience, explicitly modeling business processes as a saga avoids many of the challenges of distributed transactions, while at the same time has the added benefit of making what might otherwise be implicitly modeled processes much more explicit and obvious to your developers.

Loss of atomicity. When splitting data across multiple services, the guarantee of ACID (Atomicity, Consistency, Isolation, Durability) transactions across the entire operation is lost. Each service performs its own local ACID transaction, but the overall distributed operation is no longer atomic. This leads many to consider distributed transactions like two-phase commits (2PC).

Problems with 2PC:

  • Locking: 2PC relies on locking resources across multiple services for the duration of the transaction, leading to contention, deadlocks, and significant latency.
  • Failure modes: Complex failure scenarios (e.g., a participant failing after voting but before committing) can leave the system in an inconsistent state, often requiring manual intervention.
  • Reduced availability: As systems grow, the likelihood of a single node failure stalling a 2PC increases, reducing overall system availability.

Sagas as an alternative. Sagas break down long-lived, distributed business processes into a sequence of local, independent transactions. If a step fails, compensating actions are triggered to undo previous transactions (backward recovery) or retry the operation (forward recovery). Sagas provide eventual consistency and force explicit modeling of business processes.

  • Orchestrated Sagas: A central orchestrator service coordinates the steps and compensating actions.
  • Choreographed Sagas: Services react to events, distributing responsibility and reducing coupling, but making overall process tracking more complex.

Sagas are generally preferred over distributed transactions in microservice architectures because they avoid global locks, improve availability, and make complex business workflows explicit, despite introducing eventual consistency.

8. Anticipate and invest in new operational capabilities for distributed systems.

We replaced our monolith with microservices so that every outage could be more like a murder mystery.

Increased complexity. As the number of microservices grows, operational challenges multiply. Monitoring, troubleshooting, and managing deployments become significantly more complex than with a monolithic application. What was once a binary "up or down" state for a monolith becomes a nuanced landscape of partial failures and degraded services.

Key operational challenges:

  • Log aggregation: Centralizing logs from numerous, often short-lived service instances for effective searching and alerting.
  • Distributed tracing: Tracking a single request's journey across multiple services to identify latency bottlenecks and failure points (e.g., using correlation IDs and tools like Jaeger).
  • Desired state management: Automating the deployment, configuration, and scaling of many service instances (e.g., using Kubernetes or Function-as-a-Service platforms).
  • Testing in production: Using synthetic transactions to continuously verify critical user journeys in the live environment.

Proactive investment. These problems tend to manifest as systems scale, but proactive investment in these capabilities is crucial. Log aggregation, for instance, should be an early priority. Organizations must evolve their operational practices, tools, and team skills to manage the inherent complexity of distributed systems, moving towards an "observability" mindset that allows asking open-ended questions of the system's behavior.

9. Diligently manage service contracts to prevent breaking changes.

When you make a change to your service, you need to make sure you don’t break this contract; otherwise, nasty production issues can occur.

Independent deployability depends on stable contracts. For microservices to be independently deployable, changes to one service must not break its consumers. The contract a service exposes (its API, data schema, expected behavior) must be managed carefully. Accidental breaking changes are a common early pain point, leading to production outages or forced "lock-step" deployments of multiple services.

Strategies for contract management:

  • Eliminate accidental breakages: Use explicit schemas (e.g., OpenAPI, Protocol Buffers) to detect structural incompatibilities. Avoid technologies that magically generate schemas, preferring manual definition to force conscious thought about changes.
  • Prefer expansion over modification: Whenever possible, add new functionality (new methods, resources) rather than altering existing ones. This allows consumers to gradually migrate to new versions without immediate disruption.
  • Support multiple contracts: If a breaking change is unavoidable, the service should temporarily support both the old and new contracts (e.g., different API versions on different endpoints) to give consumers time to migrate. Running two separate versions of the service is an alternative, but adds operational overhead.

Communication is vital. Effective communication with service consumers is paramount. Treat them as customers, providing clear deprecation policies and ample time for migration. Neglecting contract management can quickly undermine the benefits of a microservice architecture, leading to a tangled "distributed monolith."

10. Balance local team autonomy with global architectural consistency.

Fundamentally, each organization needs to find the right balance between global and local decision-making.

Autonomy vs. consistency. As microservice architectures scale across multiple teams, a tension emerges between empowering individual teams to make local decisions (e.g., choosing their preferred database or deployment method) and maintaining a degree of global architectural consistency. Unchecked local optimization can lead to a proliferation of technologies and approaches, increasing overall complexity and reducing efficiency.

Signs of imbalance:

  • Multiple teams solving the same problem in different ways, unaware of each other's efforts.
  • Difficulty in developers moving between teams due to vastly different tech stacks and deployment processes.
  • Unjustified proliferation of technologies (e.g., three different databases for similar use cases).

Finding the right balance:

  • Reversible vs. Irreversible decisions: Encourage local teams to make reversible decisions quickly, but involve broader consensus for irreversible ones (e.g., adopting a new core technology).
  • Cross-cutting groups: Establish technical leadership forums or communities of practice where teams can share challenges, discuss solutions, and identify opportunities for global optimization.
  • Shared platforms/tooling: Invest in common platforms (like managed Kubernetes or FaaS) and standardized tooling to reduce the operational burden and learning curve for teams, while still allowing flexibility within those frameworks.

The goal is not rigid standardization, but rather a conscious balance that leverages team autonomy for speed and innovation while ensuring the overall system remains manageable and efficient. This balance is dynamic and requires continuous adjustment.

11. Microservices are not a universal solution; assess your context honestly.

A monolithic architecture is a choice, and a valid one at that. It may not be the right choice in all circumstances, any more than microservices are—but it’s a choice nonetheless.

Monoliths have advantages. Despite the hype, monolithic architectures offer significant benefits, especially for smaller teams or nascent products:

  • Simpler deployment: Fewer moving parts, easier to manage.
  • Easier development: Simpler developer workflows, debugging, and end-to-end testing.
  • Code reuse: Easier to share code within a single codebase.
  • Transactional integrity: ACID transactions are straightforward within a single database.

When microservices are a bad idea:

  • Unclear domain: Premature decomposition with an immature understanding of the business domain often leads to incorrect service boundaries and high costs of change.
  • Startups: Early-stage companies need to prioritize product-market fit and rapid iteration; the overhead of microservices can be a significant distraction.
  • Customer-installed software: Deploying and managing a distributed system is complex; expecting customers to handle this complexity is often unrealistic.
  • No clear reason: Adopting microservices without a specific, measurable goal is a recipe for failure.

Honest self-assessment. The decision to move to microservices should be rooted in a pragmatic assessment of your organization's specific challenges, capabilities, and culture. Don't copy others blindly. Start small, learn continuously, and be prepared to revert or adjust your strategy. A modular monolith, for instance, can offer many benefits of decomposition without the full complexity of a distributed system, serving as an excellent stepping stone or even a final destination for many organizations.

Follow
Listen
Now playing
Monolith to Microservices
0:00
-0:00
Now playing
Monolith to Microservices
0:00
-0:00
1x
Queue
Home
Swipe
Library
Get App
Try Full Access for 3 Days
Listen, bookmark, and more
Compare Features Free Pro
📖 Read Summaries
Read unlimited summaries. Free users get 3 per month
🎧 Listen to Summaries
Listen to unlimited summaries in 40 languages
❤️ Unlimited Bookmarks
Free users are limited to 4
📜 Unlimited History
Free users are limited to 4
📥 Unlimited Downloads
Free users are limited to 1
Risk-Free Timeline
Today: Get Instant Access
Listen to full summaries of 26,000+ books. That's 12,000+ hours of audio!
Day 2: Trial Reminder
We'll send you a notification that your trial is ending soon.
Day 3: Your subscription begins
You'll be charged on Jun 6,
cancel anytime before.
Consume 2.8× More Books
2.8× more books Listening Reading
Our users love us
600,000+ readers
Trustpilot Rating
TrustPilot
4.6 Excellent
This site is a total game-changer. I've been flying through book summaries like never before. Highly, highly recommend.
— Dave G
Worth my money and time, and really well made. I've never seen this quality of summaries on other websites. Very helpful!
— Em
Highly recommended!! Fantastic service. Perfect for those that want a little more than a teaser but not all the intricate details of a full audio book.
— Greg M
Save 62%
Yearly
$119.88 $44.99/year/yr
$3.75/mo
Monthly
$9.99/mo
Start a 3-Day Free Trial
3 days free, then $44.99/year. Cancel anytime.
Unlock a world of fiction & nonfiction books
26,000+ books for the price of 2 books
Read any book in 10 minutes
Discover new books like Tinder
Request any book if it's not summarized
Read more books than anyone you know
#1 app for book lovers
Lifelike & immersive summaries
30-day money-back guarantee
Download summaries in EPUBs or PDFs
Cancel anytime in a few clicks
Scanner
Find a barcode to scan

We have a special gift for you
Open
38% OFF
DISCOUNT FOR YOU
$79.99
$49.99/year
only $4.16 per month
Continue
2 taps to start, super easy to cancel
Settings
General
Widget
Loading...
We have a special gift for you
Open
38% OFF
DISCOUNT FOR YOU
$79.99
$49.99/year
only $4.16 per month
Continue
2 taps to start, super easy to cancel