093 · MICROSERVICES · BOUNDED CONTEXT · API

Microservices Architecture

Split functionality into independently deployable services around business domains.

If you are new here: Microservices architecture is the approach of building a system as a collection of small, independently deployable services — each owned by one team, responsible for one business domain, backed by its own database. Instead of one large monolith that does everything, you have an Orders service, an Inventory service, a Payments service, and so on. Each service can be deployed independently, scaled independently, and written in the language that best fits its job. The gains are real: team autonomy, granular scaling, fault isolation. So are the costs: distributed system complexity, network calls between services, and significant operational overhead. Microservices are not always better — they're a trade-off that pays off at a specific team and traffic scale.

TermPlain meaning
MicroserviceA small, independently deployable service responsible for one business capability
Bounded contextA DDD concept: the explicit boundary within which a domain model is defined and consistent
Service meshInfrastructure layer handling service-to-service networking (mTLS, retries, tracing)
API GatewayEntry point that routes client requests to the right downstream microservice
Polyglot persistenceEach service uses the database technology best suited for its data (Postgres, Redis, Cassandra)
Polyglot programmingEach service can use the programming language best suited for its workload
Distributed tracingTracking a request as it flows through multiple services (Jaeger, Zipkin, Datadog)
Circuit breakerA pattern that stops calling a downstream service that's repeatedly failing
Conway's LawSystems tend to mirror the communication structure of the teams that build them

The Problem Microservices Solve

As a monolith grows, two things break down: team coordination and deployment velocity.

Team coordination: 50 engineers all working in the same codebase. Every merge conflicts with someone else. Every test run takes 45 minutes because it runs tests for every team's code. Every deployment requires all teams to coordinate. Teams are constantly blocked on each other. A bug in the Payments module needs the Payments team to wait for the Inventory team's release to go out first.

Deployment velocity: at Netflix scale, they need to deploy hundreds of times per day. With a monolith, each deployment is a full rebuild and test cycle. You can't ship a bug fix in 10 minutes — you have to wait for the next scheduled deployment window.

Microservices solve this by drawing hard boundaries between teams. The Payments team owns the Payments service. They deploy it whenever they want. Their deployments don't require sign-off from the Inventory team. The Payments service's tests run in 3 minutes (only testing Payments code). They ship 10 times a day if they want to.

In plain terms: microservices are primarily an organizational tool — they give teams the independence to move at their own speed. The technical benefits (scaling, fault isolation) are real but secondary.

Analogy: A city versus a single giant building. A city has independent buildings — a hospital, a school, shops. If the school floods, the hospital still operates. You can renovate the school without moving out of the hospital. The trade-off: the city needs infrastructure (roads, utilities, zoning) that a single building doesn't. Microservices are the city model: more overhead, but each piece is independent.

Independent Deployment: The Core Win

The single most valuable property of microservices is independent deployment. Each service has its own:

  • Source repository (or at least a clear module boundary in a monorepo)
  • CI/CD pipeline that builds and tests only that service's code
  • Deployment schedule — no coordination with other services required
  • Version history — you can roll back Payments v3.0 to v2.9 without touching Orders

This means a team can ship a fix in 15 minutes: push code, CI builds and tests in 3 minutes, deployment pipeline ships in 5 minutes, done. No waiting for other teams. No global deployment freeze windows.

In plain terms: independent deployment is what "team autonomy" actually means in practice. If your monolith deploys once a week because coordinating all teams takes that long, you're shipping 52 times per year. Netflix ships thousands of times per day per service — the compounded advantage over years is enormous.

Tiny example: a bug is found in the Payments service at 2pm on a Friday. The Payments team:

  1. Pushes a fix at 2:05pm
  2. CI pipeline: tests pass at 2:08pm
  3. Deployment to staging at 2:10pm
  4. Deployment to production at 2:15pm

10 minutes from discovery to production fix, with no impact on the Orders or Inventory teams. In a monolith, this fix would wait until Monday's deployment window or require a risky emergency deployment of the entire application.

Service Communication: The Core Cost

When Orders needs to check inventory, it can no longer call inventory.checkStock(itemId). It must make a network call: GET https://inventory-service/api/v1/stock/item-5512.

This network call adds latency, introduces failure modes, and requires contract management:

Latency: even a local call takes 1–5ms. A checkout flow that makes 5 sequential service calls adds 5–25ms of pure network overhead, plus service processing time.

Failure modes: the network can time out, the downstream service can crash, DNS can be slow. Every service-to-service call is a new category of failure that didn't exist in the monolith.

API contracts: services must maintain stable APIs. If Orders calls Inventory's /stock/{id} endpoint and Inventory changes its response schema, Orders breaks. You now need API versioning, contract testing, and backward compatibility management.

In plain terms: every function call you convert to a network call adds a whole new failure mode and latency budget. You must design for it explicitly.

Concrete sketch: Amazon checkout: to display one checkout page, the frontend calls the API gateway, which calls Orders, Cart, Inventory, Pricing, Recommendations, Shipping, and User Profile services. That's 7 network calls, potentially 30–100ms of latency per call if not parallelized. Amazon invests heavily in parallel calls, local caches, and circuit breakers to keep this fast.

Failure Isolation: A Real Benefit

In a monolith, a memory leak or infinite loop in one module can take down the entire application. In microservices, that same bug only crashes the service it's in. Other services continue serving traffic.

When the Inventory service is down:

  • Orders that don't need inventory checks (e.g., digital goods) continue normally
  • Orders that need inventory return a graceful error ("inventory temporarily unavailable") rather than a 500 error
  • Payments, Auth, and User Profile services are completely unaffected

The key is designing for partial failure. Services must not blindly assume their dependencies are available. They need circuit breakers, fallback responses, and graceful degradation.

In plain terms: in microservices, failures are contained to the service that broke. The blast radius is smaller. But this only holds if you design for it — if every service has a circuit breaker and fallback, not if they just crash and wait for recovery.

Concrete sketch: Netflix Chaos Monkey is a tool that randomly kills services in production. Netflix uses it specifically because microservices should survive individual service failures. If Chaos Monkey kills the Recommendations service, Netflix should still stream video — recommendations just show cached results or defaults. Testing this in production is how Netflix verifies their fault tolerance.

When NOT to Use Microservices

The industry has overcorrected. Microservices became fashionable, and many teams adopted them before they were ready, creating distributed systems nightmares:

  • Team too small: fewer than 10 engineers means you don't have the team autonomy problem that microservices solve. You just added distributed systems complexity for no benefit.
  • Product too immature: if your domain boundaries aren't well understood, you'll draw the service boundaries wrong and spend months untangling the mess.
  • No observability: distributed tracing, centralized logging, and service monitoring are prerequisites. Without them, debugging a bug that spans 5 services is a nightmare.
  • No CI/CD maturity: if you can't automate deployments, running 20 services with manual deployments is chaos.

The Bezos mandate (Amazon 2002): Jeff Bezos mandated that all teams must expose their data through service APIs. But Amazon spent years building the infrastructure before that mandate was achievable. They built the deployment tools, monitoring, and API gateway first.

The Trade-offs

PropertyMicroservicesMonolith
Team autonomyHigh — independent deploymentsLow — shared codebase and deployments
Scaling granularityFine — scale individual servicesCoarse — scale the whole app
Fault isolationHigh — blast radius limited to one serviceLow — one bug can crash everything
Operational overheadHigh — N services to deploy, monitor, debugLow — one thing to run
Distributed tracingRequired — cross-service request trackingNot needed
Transaction complexityHigh — no shared ACID transactionsLow — one DB
Right team size20+ engineers with DevOps maturity1–20 engineers

Why this matters for you

The microservices vs monolith debate is one of the most contentious in software engineering — and both sides have real points. The key insight: microservices are an organizational solution, not a technical one. They exist to give teams independence. If your team doesn't have the coordination problems microservices solve, you're paying the distributed systems costs without getting the organizational benefits. Before breaking up a monolith, ask: "Is our velocity limited by deploy coordination?" If yes, microservices help. If your team can deploy the monolith independently already, microservices will only add complexity.

Next: Serverless Architecture — what if you removed the concept of "services" entirely and just deployed functions?

DIAGRAMDrag nodes · pan · pinch or double-click to zoom
FRAME 1 OF 5

Microservices — each business domain is an independent service with its own database and deployment lifecycle.