MODULE 1/LESSON 1
🔀 Monolith to Microservices

Why & When to Migrate

Understanding when monolithic architecture becomes a liability and why microservices solve it

⏱ 12 min📊 Diagram
Monolithic architecture is excellent for early-stage products — it's simple, easy to deploy, and has low operational overhead. But as teams and products grow, it accumulates three critical failure patterns that force migration to microservices.

Key Concepts

Independent Scaling

Scale only the overloaded service (e.g., Product Search) without wasting compute on idle modules. This alone can cut infrastructure costs 40–70% at scale.

Deployment Autonomy

Deploy a payment bug fix without touching the catalog service. 50-person teams shipping 10x/day instead of weekly big-bang releases.

Conway's Law

Your system architecture mirrors your team structure. Domain-split microservices let 2-pizza teams own full service lifecycle — deploy, monitor, on-call.

When NOT to Migrate

Startups under 10 engineers, MVPs, monorepos with clear domain separation, and systems without measurable scaling pain should stay monolithic.

The Three Monolith Pain Points

Each pain point represents a hard ceiling that cannot be solved within a monolith. At a certain scale, you must break the monolith or accept permanent velocity loss.
Pain PointMonolith ProblemMicroservice Solution
Deployment1 bug fix = full system redeploy + full test suite run (hours)Deploy affected service only in minutes
ScalingScale everything or nothing — 100% resource waste on idle modulesScale only the bottleneck service independently
Team VelocityMerge conflicts, shared schema, 500-test suites — shipping slowsTeams own isolated codebases, deploy independently
TechnologyStuck on one language/DB stack foreverRight tool per domain — Postgres for orders, Redis for sessions, Elasticsearch for search

Migration Strategies Overview

  • Strangler Fig Pattern — Incrementally extract services behind an API Gateway; never Big Bang rewrite
  • Domain-Driven Design (DDD) — Identify Bounded Contexts before drawing service boundaries
  • Database per Service — Each service owns its data. No shared schema. Cross-service queries via events or APIs only
  • Saga Pattern — Replace distributed ACID transactions with choreographed compensating actions

Architecture Comparison

Monolithic Architecture Single Application (Node.js) Auth Orders Catalog & Payments Shared Database (Postgres) Microservices Architecture API Gateway Auth Svc Auth DB Order Svc Order DB Kafka Event Bus (Async) Payment

The Microservices Tax (Hidden Costs)

  • **Observability:** You can no longer rely on simple stack traces. You must implement Distributed Tracing (Jaeger, OpenTelemetry) to track a request across 10 different services.
  • **Network Latency:** Local function calls (`0.1ms`) are replaced by network HTTP/gRPC calls (`5-50ms`). Over-chatty microservices will grind to a halt.
  • **Data Consistency:** ACID guarantees are gone. If the Order Service succeeds but Payment Service fails, you must manually implement distributed rollbacks (Sagas).
  • **Infrastructure Overhead:** Instead of 2 VMs, you now manage Kubernetes, API Gateways, Service Meshes, CI/CD pipelines for 50 repos, and an Event Broker (Kafka).

Real-World Example: Shopify's Migration

Shopify operated as a Rails monolith for 12 years. As they scaled past 1M merchants, they hit all three pain points simultaneously. Their solution was a gradual strangler fig — introducing a Modular Monolith phase first (isolating domain boundaries without network boundaries), then progressively extracting high-load domains like Checkout and Storefront into independent services.
💡
Senior Architect Insight: Rule of thumb: Stay monolithic until you have >5 engineering teams shipping independently, sustained database connection pool exhaustion, or modules with wildly different scaling curves (e.g., search vs. checkout). Migration costs are real — don't pay them early.