Menu
Course/Architectural Styles/Monolith vs Microservices

Monolith vs Microservices

The foundational architectural choice: monolithic simplicity vs microservice flexibility. Migration strategies, team structure implications, and decision criteria.

18 min readHigh interview weight

The Foundational Choice

Every system starts somewhere. The first major architectural decision you make — often before writing a single line of code — is whether to build a monolith or a microservices system. This choice ripples through team structure, deployment strategy, operational complexity, and long-term velocity. Getting it wrong is expensive, but understanding the trade-offs lets you make the right call for your context.

What Is a Monolith?

A monolith is a single deployable unit containing all application functionality. The UI layer, business logic, and data access code are packaged and deployed together. When you push a change to any part of the system, you redeploy the whole thing. Early-stage companies like Shopify, Stack Overflow, and GitHub ran — and in some cases still run — massive monoliths successfully.

Loading diagram...
A monolith: all layers run inside a single deployable process

Monolith Advantages

  • Simple to develop: One codebase, one IDE, one debugger. No network calls between internal components.
  • Easy to test end-to-end: All components are in-process; integration tests don't require spinning up multiple services.
  • Low operational overhead: One service to deploy, monitor, and scale.
  • No distributed systems problems: No partial failures, no network partitions between components, no eventual consistency headaches.
  • Strong consistency: All business logic shares one database transaction boundary.

Monolith Disadvantages

  • Scaling is coarse-grained: You must scale the entire app even if only the image-processing component is under load.
  • Deployment coupling: A bug in the payments module can block a deploy for the user-profile feature.
  • Technology lock-in: The entire codebase must use the same language, framework, and runtime version.
  • Organizational friction: As the team grows, merge conflicts and coordination costs increase.
  • Startup time: Large monoliths can take minutes to boot, slowing development feedback loops.

What Are Microservices?

Microservices decompose the application into small, independently deployable services, each owning a bounded domain. Amazon, Netflix, and Uber pioneered this style at scale. Each service has its own process, its own database, and communicates with others over a network (typically HTTP/REST, gRPC, or a message broker).

Loading diagram...
Microservices: each service owns its domain and database, communicates via API or events

Microservices Advantages

  • Independent deployability: Teams deploy their service without coordinating with others.
  • Fine-grained scaling: Scale only the bottleneck service (e.g., add replicas of the recommendation service during peak traffic).
  • Technology diversity: Each service can choose the best language or database for its workload.
  • Fault isolation: A crash in the notification service doesn't take down the order service.
  • Team autonomy: Conway's Law works in your favor — small teams own small services end-to-end.

Microservices Disadvantages

  • Distributed systems complexity: Network calls fail, services become unavailable, latency spikes. You must handle retries, timeouts, circuit breakers.
  • Data consistency: Cross-service transactions require sagas or eventual consistency patterns — there is no distributed ACID transaction.
  • Operational overhead: Dozens of services require service discovery, load balancing, centralized logging, distributed tracing, and a service mesh.
  • Integration testing is hard: Spinning up a representative local environment requires orchestration (Docker Compose, Kubernetes).
  • Latency: An API call that was previously an in-process function call is now a network hop with serialization overhead.

Head-to-Head Comparison

DimensionMonolithMicroservices
DeploymentSingle artifactPer-service artifacts
ScalingWhole-app scalingPer-service scaling
Team structureShared codebaseTeam per service
Data managementShared databaseDatabase per service
Failure isolationLow — one crash kills allHigh — faults are contained
Operational complexityLowHigh
ConsistencyStrong (ACID)Eventual (saga/outbox)
Best forEarly stage, small teamsScale, large orgs, autonomy

When to Choose Each

💡

Start with a Monolith

Martin Fowler's advice remains sound: start with a well-structured monolith (a 'modular monolith'). Microservices should be introduced when you have a clear scaling or team-autonomy problem — not as a default starting point. Amazon, Shopify, and GitHub all built successful monoliths first.

Choose a monolith when: the domain is not yet well-understood, the team is small (fewer than ~15 engineers), deployment velocity is more important than independent scalability, or you are building an MVP.

Choose microservices when: you have distinct scaling requirements per domain, you have multiple teams that need to deploy independently, your reliability budget requires fault isolation, or you are integrating with external services that map cleanly to service boundaries.

Migration: Monolith to Microservices

The Strangler Fig pattern (named after a fig tree that grows around and eventually replaces the host tree) is the standard migration approach. You route specific request paths to new microservices while the old monolith handles the rest. Over time, you strangle the monolith as services absorb its responsibilities.

pseudocode
// Strangler Fig — API Gateway routing rule (pseudocode)

function route(request):
  if request.path starts with "/payments":
    forward to PaymentsMicroservice
  elif request.path starts with "/recommendations":
    forward to RecommendationsMicroservice
  else:
    forward to LegacyMonolith   // still handles the rest
⚠️

Avoid the 'Distributed Monolith' Anti-Pattern

The worst outcome is a distributed monolith: you split the codebase into separate services, but they share a single database and require coordinated deployments. You get all the costs of microservices with none of the benefits. The key rule: each service must own its data.

💡

Interview Tip

In interviews, when asked 'would you use microservices?', never answer with a simple yes or no. Walk through the trade-offs: team size, domain clarity, operational maturity, and scaling requirements. Show that you understand microservices introduce distributed systems problems (network partitions, eventual consistency, distributed tracing) that must be handled explicitly. Bonus: mention the Strangler Fig pattern for migration.

📝

Knowledge Check

5 questions

Test your understanding of this lesson. Score 70% or higher to complete.

Ask about this lesson

Ask anything about Monolith vs Microservices