System Design/
Lesson

MicroservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data. are powerful at the right scale, but the industry conflated "what works for Netflix at 200 million users" with "what works for a startup at 200 users."

Real reasons to adopt microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data.

Four problems that microservices solve well. If you don't have at least one, a monolithWhat is monolith?A software architecture where the entire application lives in a single codebase and deploys as one unit. Simpler to build and debug than microservices. is almost certainly better.

1. Independent scaling

Different parts of your system have different resource needs. In a monolith, you scale everything together. With microservices, you run 20 instances of your image processor and 2 of your admin panel.

yaml
# Kubernetes: scale services independently
apiVersion: apps/v1
kind: Deployment
metadata:
  name: image-processor
spec:
  replicas: 20  # CPU-intensive, needs many instances
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-api
spec:
  replicas: 2   # Low traffic, minimal resources needed

2. Team autonomy

With 50+ engineers on one codebase, merge conflicts become daily events and deploys become coordination exercises. Microservices let teams own their service end-to-end: deploy schedule, testing strategy, even programming language. This is fundamentally an organizational argument, mapping directly to Conway's Law.

3. Fault isolation

In a monolith, a memory leakWhat is memory leak?When your program holds onto memory it no longer needs, causing usage to grow over time until performance degrades or it crashes. in reporting can crash the entire application. With microservices, a crashed recommendation service shows fallback content while the restWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. keeps working.

// API Gateway with fallback
async function getProductPage(productId: string) {
  const product = await productService.get(productId);  // Required

  let recommendations;
  try {
    recommendations = await recommendationService.get(productId);
  } catch (err) {
    recommendations = await fallbackPopularItems();  // Graceful degradation
    logger.warn('Recommendation service unavailable', { productId });
  }

  return { product, recommendations };
}

4. Different tech stacks

Your ML team writes Python, your APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. team writes TypeScript. With microservices, each team picks the best tool. Valid but often overstated, polyglot architectures add operational complexity.

02

Bad reasons to adopt microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data.

Bad reasonWhy it's wrongWhat to do instead
"Netflix/Google/Amazon does it"They have 10,000+ engineers and billions of usersBuild for your actual scale
Resume-driven development"I want microservices on my CV"Optimize for your product, not your resume
"Microservices are modern"Monoliths are not legacy by definitionChoose architecture based on constraints
"We need to be ready to scale"Premature architecture is premature optimizationScale when you need to, not before
"Our monolith is messy"Messy code stays messy across servicesClean up the monolith first
"We want independent deploys"Modular monolith with feature flags achieves thisTry the simpler solution first

If you can't deploy one service reliably, you definitely can't deploy twenty.

03

Prerequisites: what you need before microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data.

Microservices shift complexity from your codebase to your infrastructure. You need infrastructure maturity to handle that shift.

PrerequisiteMaturity level requiredWhy it matters
CI/CD pipelineAutomated, reliable, per-serviceYou'll deploy 10-50x more often
ContainerizationDocker + orchestration (K8s)Services need isolation and portability
ObservabilityDistributed tracing, centralized loggingDebugging crosses service boundaries
Service discoveryDNS or service meshServices need to find each other
Automated testingIntegration + contract testsCan't manually test cross-service flows
DevOps cultureTeam owns build + deploy + monitorNo separate "ops team" to bottleneck
Incident responseOn-call rotation, runbooksMore services = more failure modes
API versioningBackward-compatible changesServices evolve independently

If you're missing more than two items, you're not ready.

04

The team size heuristic

You need roughly one team (3-7 people) per service, plus a platform team. If you have 8 engineers and 12 microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data., "ownership" becomes "nobody maintains it until it breaks at 2am."

Team size → Architecture mapping

1-5 engineers    → Monolith (maybe modular)
5-20 engineers   → Modular monolith, maybe 2-3 services for genuinely different workloads
20-50 engineers  → Microservices start making sense (5-10 services)
50-200 engineers → Microservices with platform team
200+ engineers   → Full microservices with service mesh, internal platform
05

The strangler fig migrationWhat is migration?A versioned script that changes your database structure (add a column, create a table) so every developer and server stays in sync.

Don't rewrite everything at once. The strangler fig pattern lets you migrate incrementally: put a proxy in front of your monolithWhat is monolith?A software architecture where the entire application lives in a single codebase and deploys as one unit. Simpler to build and debug than microservices., build new features as services, and gradually move existing functionality out.

Before:
Client → Monolith (handles everything)

During migration:
Client → API Gateway → /users    → Monolith (still handles users)/orders   → Order Service (extracted)/payments → Payment Service (extracted)/*        → Monolith (handles the rest)

After:
Client → API Gateway → Individual services

If the new service has problems, traffic goes back to the monolith.

06

Decision framework

  1. Do different parts need different scaling? If the cost difference is significant, microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data. help.
  2. Are teams blocking each other on deploys? If you've tried feature flags and modular code first, microservices help.
  3. Do you have the infrastructure maturity? If no, invest there first.
  4. Is your team large enough? Fewer than 15-20 engineers, probably not.
  5. Do you know your domain boundaries? If no, keep the monolithWhat is monolith?A software architecture where the entire application lives in a single codebase and deploys as one unit. Simpler to build and debug than microservices..
07

Quick reference

FactorFavor monolithFavor microservices
Team size< 20 engineers> 20 engineers
Deploy frequencySame across featuresVaries significantly per team
Scale requirementsUniformDifferent per component
Domain knowledgeStill learning boundariesWell-understood, stable boundaries
Infrastructure maturityEarly stageCI/CD, containers, observability in place
Data consistency needsStrong ACID neededEventual consistency acceptable
AI pitfall
AI will suggest extracting a service "when it becomes a bottleneck." What AI gets wrong: a PostgreSQL monolith handles thousands of requests per second. Most startups will fail for business reasons long before a monolith becomes the limiting factor.
Good to know
The strangler fig pattern is the safest migration approach. Build the new service alongside the monolith, gradually route traffic to it. If problems arise, route traffic back. No big-bang rewrite.
Edge case
Database ownership is the hardest part of splitting a monolith. Two services sharing tables are not independent, a schema change in one breaks the other. Before extracting a service, identify which tables it exclusively owns.