Microservices: Bounded-Context Sized, Independently Deployed
What This Concept Is
Microservices is an architectural style that structures an application as a collection of small, independently deployable services, each aligned to a business capability. The canonical definition comes from Lewis & Fowler (2014): "a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API."
Defining properties (all must hold, or it is something else):
- Bounded-context sized. One service owns one business capability. Not a CRUD endpoint; not the whole monolith. The bounded-context concept from DDD (M03) is the correct granularity rule.
- Independently deployable. Team A can deploy service X without coordinating with team B's service Y. Not aspirational; actually true. If every release requires cross-team sync, you do not have microservices.
- Data isolation. Each service owns its data. No other service reads or writes the database directly. Cross-service data access is through the service API.
- Decentralized governance. Each service picks its own language, framework, and DB within team constraints. Not "mandated by platform to use only Spring and Postgres."
- Failure-in-isolation. One service failing does not take out the system. Circuit breakers, timeouts, and graceful degradation are required.
- Smart endpoints, dumb pipes. Business logic lives in services, not in an enterprise bus. Communication is simple (REST, gRPC, lightweight events).
A common topology:
+--------+
| UI |
+---+----+
|
v
+---- API gateway ----+
| | | | |
v v v v v
+----+ +----+ +----+ +----+ +-----+
| S1 | | S2 | | S3 | | S4 | | ... | (10-100+ services)
+--+-+ +--+-+ +--+-+ +--+-+ +--+--+
| | | | |
v v v v v
[db1] [db2] [db3] [db4] [db5] (each owns its data)
+ event bus connecting some services asynchronously
+ observability: tracing, metrics, logs across all services
Why It Matters Here
Microservices is the style most commonly mis-picked. Teams reach for it because it is the current fashion and end up paying a very high price for benefits they did not need. This module spends three concepts on microservices (Concepts 10, 11, 12) specifically because the gap between "what the style is" and "what teams commonly build" is so large.
To know when microservices is the right answer, you must know what it actually is. Bulleted lists are cheap; independently deployable in practice is not.
Concrete Example
OrderFlow as a microservices system:
- ~15 services, each bounded-context-sized:
catalog,pricing,inventory,checkout,payments,fraud,fulfillment,shipping,notifications,loyalty,returns,billing,accounts,search,recommendations - each service owns its schema in its own Postgres or a document DB where appropriate
- each team owns 1-3 services end-to-end (build, deploy, operate, on-call)
- service-to-service via gRPC for low-latency internal calls; async events over Kafka for fan-out
- an API gateway fronts public traffic and handles auth, rate limiting, fan-out to multiple services for aggregated views
- every service has: health endpoint, metrics, structured logs, trace propagation
- shared platform: auth, logging, metrics, tracing, CI templates -- built and maintained by a platform team
Every team can deploy any hour of any day. An outage in recommendations does not bring down checkout; the UI hides the recommendation rail and keeps the checkout button live. A schema change in billing does not ripple into catalog because catalog does not touch billing's DB.
Bounded-context sizing, with examples
A bounded context is a region of the domain model where certain terms have consistent meaning. Some guidance:
Productin catalog: the thing customers browse. Fields: title, description, images, category.Productin pricing: the thing we compute a price for. Fields: product_id, base_cost, discount_rules.Productin fulfillment: the thing we physically pack. Fields: product_id, weight, dimensions, pick_location.
Each is correctly a different bounded context, and each is a candidate for its own service. Merging them "because they share the word Product" is how you end up with a single service that is actually three systems.
Anti-pattern sizing: nanoservices -- one REST endpoint per service. Total overhead dwarfs total work. Granularity has a floor.
Common Confusion / Misconception
"Microservices means small services." Small by bounded-context, not small by line count. A service implementing payments correctly is not "small" -- it has retries, webhooks, reconciliation, reporting, fraud flags, state machines. It is right-sized for one capability. The size adjective is about responsibility, not lines of code.
"HTTP = microservices." HTTP is a communication mechanism. A modular monolith can expose HTTP; a microservices system can use gRPC or events. The defining property is independently deployable bounded-context services, not the wire protocol.
"Microservices replace the monolith." This is the most expensive misconception in this module. Microservices are a distributed monolith if:
- services share a DB (concept 7 is then more appropriate)
- services cannot deploy independently (change X requires change Y)
- there is no failure isolation
A system with those properties is worse than a monolith, not better.
"Microservices is about scale." It is partially about scale, but more about independent deployability and team autonomy. Scale can be achieved with space-based or service-based or sharding. Independent deploy per team is what microservices uniquely offer.
"Every service needs its own DB server." Each service owns its schema and is the only writer. The physical DB server can be shared for cost reasons in early stages (be explicit about this in ADRs). The rule is ownership, not physical isolation.
How To Use It
If you have concluded microservices is appropriate (see Concept 12 before you decide), adoption checklist:
Minimum platform capabilities you must have before the first extraction:
- Centralized auth with a token that propagates.
- Structured logs with correlation IDs.
- Distributed tracing (OpenTelemetry, Datadog, Honeycomb, etc.).
- Metrics (RED: rate, errors, duration) per service.
- CI template that new services can inherit.
- A service discovery or API gateway layer.
- A policy for inter-service communication (REST vs gRPC vs events) and when each is used.
- An on-call rotation model -- each team owns the operations of their service.
If three or more of these are "we'll figure it out later," do not extract. The extraction is the easy part; the platform is 80% of the work, and half the teams that fail at microservices failed because they skipped the platform.
Check Yourself
- Name the six defining properties of microservices. For each, name what the system looks like when the property is violated.
- What is the difference between microservices and service-based architecture (Concept 7)? Give three.
- Why is "bounded context" the right sizing unit rather than "line count" or "team size"? What would a team-sized service miss?
Mini Drill or Application
Take a system you know. In 25 minutes:
- List at least 8 candidate bounded contexts.
- For each, decide: "separate service" or "merge with a sibling." Explain in one sentence why.
- List the minimum platform capabilities you would need before extracting the first one. Mark which ones your team actually has.
- Pick the service you would extract first. Defend the order in two sentences.