Teams usually start asking about microservices after the application has grown too big to change or release without something breaking. The style tends to fit best where a small team can own a service from build to production.
Each service covers one business capability, runs as its own process and deploys independently. Services reach each other over the network through APIs or messages, and every one keeps its own database.
JetBrains’ 2022 Developer Ecosystem Survey found that 37% of respondents build software this way, two percentage points above its 2021 result.
What Are Microservices?

The easiest way in is to look at what they replace. A monolith ships all of its logic as one deployable unit. Microservices split that logic into small services, each owning one business capability and deployable on its own, running as separate processes that talk to each other over the network.
Microsoft’s Azure Architecture Center describes them as independent and loosely coupled, and small enough for one team to write and maintain.
Where the term comes from
James Lewis presented early versions of the ideas at 33rd Degree in Krakow in March 2012. He and Martin Fowler published their definition article in March 2014, and most sources still start from it.
Fowler says he teamed up with Lewis to write the article because he was concerned that microservices had no clear definition, a fate that had caused many problems for SOA.
The article admits that no precise definition exists. It lists common characteristics instead.
Lewis has acknowledged that the term drifts from its original meaning over time, a pattern Fowler calls semantic diffusion.
What microservices are not
They are not a protocol or a product. Services talk over ordinary HTTP APIs or message queues, and no package installs the style. It is a way of drawing boundaries.
They are also not SOA with a new label, though the two are related.
- Fowler called microservices a subset of SOA in his 2014 GOTO Berlin keynote, one that avoids a central service bus and a single company-wide database (InfoQ).
The wider microservices architecture adds its own rules for how services communicate and deploy, and for who owns the data.
Which Characteristics Define Microservices?

Fowler and Lewis’s 2014 article catalogs nine characteristics, and its own summary boils them down to four themes.
Organization around business capability comes first. A service covers something like orders or payments, not one technical layer.
Deployment is automated. Provisioning, testing and release run without manual steps, and each service ships independently.
Business logic lives in the services, and the network between them only moves messages (the article’s “smart endpoints, dumb pipes”). Control is decentralized too, so each team picks its own language and owns its own database.
Boundaries follow the business

Microsoft’s guidance says each service should implement a single business capability inside a bounded context, a natural division of the business with an explicit boundary around its domain model.
Eric Evans introduced the bounded context in the modeling approach known as domain-driven design. It remains the usual test for where one service ends and the next begins.
Shared database schemas and rigid communication protocols are the two coupling causes Microsoft singles out. A practical test follows. Two services that always change together are one service.
Team size and ownership
AWS’s Well-Architected DevOps Guidance credits Werner Vogels with coining “you build it, you run it” in 2006. Amazon calls the small autonomous teams that follow it two-pizza teams, each with a single-threaded focus.
Conway’s law explains why that matters. A system’s design mirrors the communication paths of the organization that builds it, so service boundaries and team boundaries should match.
Size is a poor yardstick. Fowler noted at GOTO Berlin that people avoid putting a number on it and talk about responsibility instead, which is just as vague.
Worked example: an online store
Take an online store, the scenario Chris Richardson uses on microservices.io to introduce the database per service pattern.
- Catalog covers product data and descriptions, plus pricing rules
- Orders follow the lifecycle from placement to fulfillment
- Card and payment-provider integration sits in Payments
- Inventory tracks stock levels and reservations
Each changes for its own reason, and each owns its own data.
A bad cut separates things that change together, such as cart and checkout. Every change then touches two services and needs two coordinated releases.
That failure mode is called a distributed monolith. The services deploy separately but behave as one tightly coupled program.
How Do Microservices Communicate?

A caller can wait for a reply, as with REST or gRPC. Or a sender can publish to a broker or event stream and move on, as with RabbitMQ or Apache Kafka. Most systems mix both.
| Mechanism | Style | Fits when | Main cost |
|---|---|---|---|
| REST over HTTP | Synchronous | The caller needs the answer now | Caller waits on the callee |
| gRPC | Synchronous, binary | High-volume internal calls | Shared contract files to maintain |
| RabbitMQ | Asynchronous queue | Work can finish later | A broker to run and monitor |
| Apache Kafka | Asynchronous event stream | Many consumers read the same events | Ordering and replay design |
A monolith calls a component with one procedure call. Over the network the same call adds latency and can fail, so Fowler and Lewis recommend replacing fine-grained calls with coarser ones.
Synchronous calls
REST over HTTP is the usual starting point. Teams adopt RESTful interfaces first because every language speaks HTTP and curl is enough to debug one.
gRPC, Google’s RPC framework, sends binary Protocol Buffers messages over HTTP/2. Payloads stay small and the contract is typed.
The cost is coupling in time. If the callee is slow or down, the caller waits, and the failure travels up the chain.
Microsoft’s advice is to avoid chatty APIs and to move work to asynchronous patterns such as queue-based load leveling wherever a reply is not needed right away.
Asynchronous messaging
Async removes the waiting. The sender publishes and moves on, and the receiver processes the message when it can.
RabbitMQ works with queues that hand each message to a worker. Apache Kafka is a distributed log that keeps events, so new consumers can replay history.
Fowler and Lewis want the pipe to stay dumb. The broker moves messages, the business logic stays inside the services, and that is why they steer teams away from an enterprise service bus.
A workable rule is to start with HTTP and a queue, then add Kafka when several services need the same stream or when replay matters.
Gateway, discovery and circuit breakers
Service-to-service traffic gets easier to manage with a few supporting pieces. Clients call a gateway sitting in front of the services instead of reaching them directly. It routes requests, aggregates several calls into one, and offloads chores such as authentication, logging, SSL termination and load balancing (Microsoft Azure Architecture Center). Kong is a common product choice. Keep business rules out of it.
Service discovery handles the addresses. Instances register themselves and callers look up live ones. Netflix’s Eureka is a well-known registry.
When a service keeps failing, a circuit breaker makes calls to it fail fast instead of piling up, then lets them resume later. Resilience4j provides this for Java.
How Do Microservices Manage Data?
Each microservice owns its data and exposes it only through its own API, a rule called database per service. No other service reads its tables directly, which keeps services loosely coupled but pushes cross-service work into explicit patterns.
The payoff shows up at change time. A schema update touches one service, where a monolith would put every component that reads the table at risk (Microsoft Azure Architecture Center).
Levels of separation
Chris Richardson’s pattern catalog at microservices.io describes a range of ways to implement it.
At the light end, services share one database and each reserves its own private tables. A schema per service is a step up and makes ownership clearer. Full isolation means a database server per service, which suits high-throughput services.
Richardson rates the first two as lowest overhead. His FTGO example app runs several services on one MySQL server, with credentials that grant each service access to its own logical database only.
Consistency without shared transactions
A change that spans services is unlikely to qualify as one ACID transaction, according to Microsoft’s guidance. The saga pattern replaces the distributed transaction with a sequence of local ones.
Each step updates its own database and publishes a message or event that triggers the next step, so sagas lean on an event-driven design. If a step fails, the saga runs compensating transactions that undo the earlier steps.
In Richardson’s order example, the saga creates the order, asks the Customer Service to reserve credit, and approves or rejects the order based on the reply.
The trade-off is eventual consistency. The data converges once the saga finishes, and until then another service can read the in-between state.
Queries that span services
A join across two databases is no longer possible. Richardson offers API composition, where the caller gathers data from each service and joins it in code. The other route is CQRS, a separate read-only view kept current by subscribing to the owning services’ events.
Both add code and latency that a single database join never needed.
How Are Microservices Deployed and Monitored?
Each microservice gets its own build and release pipeline, ships as a container image, and runs on an orchestrator such as Kubernetes, while traces, metrics and logs flow from every service into shared tooling. Skipping that automation turns each added service into manual work.
Fowler’s Microservice Prerequisites post (28 August 2014) sets the baseline. A new server should be available in hours. Monitoring has to cover technical signals such as error counts and availability, and business signals such as a drop in orders. Releases to test and production should be quick, with fast rollback.
Fowler’s list also pairs these with close collaboration between developers and operations, and Microsoft’s guidance says success needs a mature DevOps culture. He adds that a monolith benefits from the same capabilities.
Containers and orchestration

Orchestrators do the placement work. Per Microsoft, the orchestrator schedules and deploys services across nodes, detects and recovers from failures, and enables autoscaling, and Kubernetes can pack a higher density of services onto one host.
Docker is the usual tool for container-based packaging, which gives every instance the same runtime wherever it runs.
CNCF’s 2025 annual survey found 82% of container users running Kubernetes in production.
Kubernetes does not require microservices. It orchestrates containers whatever the architecture, so a containerized monolith runs on it just as well.
Monitoring and distributed tracing
One user action can cross several services, so a log from a single service rarely explains a failure. Microsoft notes that logging has to correlate the multiple service calls behind one user operation.
OpenTelemetry is the vendor-neutral standard for generating traces, metrics and logs. It was formed in May 2019 by merging OpenCensus and OpenTracing, and the CNCF announced its graduation on 21 May 2026.
Prometheus collects metrics and Jaeger stores and displays traces. Both are CNCF graduated projects, as OpenTelemetry now is.
When a service mesh earns its place
A service mesh puts a proxy beside each service to handle mutual TLS, traffic routing and telemetry. Istio, built on the Envoy proxy, is the best-known one.
Istio graduated within the CNCF on 12 July 2023. As of that announcement, Istio still recommended sidecar deployments, while its sidecar-free ambient mode, launched in September 2022, was in alpha.
CNCF’s 2024 Cloud Native Survey (released April 2025) recorded service mesh adoption falling from 50% to 42%, which CNCF attributed to operational overhead concerns.
Read together, the two sources point to overhead as the mesh’s main cost and to ambient mode as Istio’s answer to it. The survey does not say how many teams moved to ambient mode instead of dropping their mesh.
Adopt a mesh when many services need uniform mutual TLS or traffic policy. Before that, a gateway and a retry library cover most needs.
Microservices vs Monolith and SOA
A monolith ships as one deployable unit. SOA, as many enterprises built it, routes services through a shared enterprise service bus.
Microservices keep the services but drop the central bus and the shared database, so each service deploys and scales on its own.
| Dimension | Monolith | SOA | Microservices |
|---|---|---|---|
| Deployment unit | One application | Separate services, release independence not guaranteed | One service at a time |
| Integration | In-process calls | Often an enterprise service bus | Direct APIs or a plain message broker |
| Data | One shared database | Often centralized | One database per service |
| Typical cost | Coordination overhead as teams grow | Services that cannot ship alone | Tooling and network latency |
Against a monolith
The monolith has real advantages. Fowler says nobody should underestimate its simplicity and familiarity. You get one codebase, one pipeline and one deployment, and calls happen in process with no network hop.
Many problems blamed on the monolithic architecture are not built into the style. In 2015 Fowler cited Facebook and Etsy as organizations that practiced continuous delivery on monoliths through cookie-cutter deployment.
The limit is discipline. A monolith can hold well-defined module boundaries in theory, Fowler writes, but in practice boundaries get breached and the code tangles as it grows.
Randy Shoup’s comparison, published on DORA’s site, lists what arrives with scale: coordination overhead, all-or-nothing deploys and long build times.
Against SOA
Fowler and Lewis both describe the approach as something teams practiced for years under the name SOA. Lewis stresses that the connection holds when SOA is understood and done right (OST Cloud Application Lab).
The practical gap is independence at release time. DORA’s research notes that many so-called service-oriented architectures do not let teams test and deploy services independently of each other, which is the outcome microservices exist to deliver.
The middle option
Between the two sits the modular monolith, one deployable application with well-defined module boundaries inside it.
It keeps in-process calls and a single pipeline while removing much of the tangling that pushes teams toward separate services.
What Do Microservices Gain and What Do They Cost?

Microservices trade simple deployment for operating work. Teams gain independent releases, fault isolation and focused ownership, and pay in tooling, version management and coordination across service boundaries.
On the plus side, you can fix or roll back one service without redeploying the application.
- Failures stay contained, provided upstream services handle them
- Only the service under load needs scaling
- Feature teams can be small enough to build, test and deploy a service alone
The costs are less obvious until you live with them.
- Too many languages and frameworks make the system hard to maintain without shared standards
- Updates to a service must not break its consumers
- Refactoring and testing across service dependencies is harder than inside one codebase
- Distributed systems reward experience, so the team’s background matters
- Many small repositories mean heavier dependency management
Both lists follow Microsoft’s Azure Architecture Center, with the tooling point taken from Shoup’s comparison on DORA’s site.
Versioning is the cost teams forget
Independent deployment only holds if consumers survive a release. DORA’s guidance recommends a versioning policy for APIs with no more than two concurrent versions and a client transition window of six months or less.
Backward-compatible APIs add complexity. DORA argues the deployment flexibility repays that cost many times over.
Service count is not the cost driver
Fowler described the premium in his May 2015 post as the work of automated deployment, monitoring, failure handling and eventual consistency.
He has seen systems range from a team of 60 running 20 services to a team of 4 running 200, and says it is unclear how service size affects the premium.
DORA’s capability page adds that the delivery outcomes are reachable on mainframes and still missed on fashionable stacks.
Put the two together and the cost follows coupling and tooling, not the label on the architecture or the raw number of services.
When to Use Microservices and When to Avoid Them

Use microservices when a monolith has become too big to change and deploy safely, and independent releases are worth the operating cost. Otherwise stay on a monolith, ideally a modular one.
Fowler’s May 2015 guideline is blunt. Do not consider microservices unless the system is too complex to manage as a monolith.
A decision rule
The case for adopting rests on a handful of signals.
- Releases wait on other teams, which DORA suggests measuring as the share of production deployments coordinated with other services
- The monolith is too big to modify and deploy, the factor Fowler ranks highest
- Large teams, multi-tenancy, many user interaction models or independent business functions add to the load
- Domain boundaries have stopped moving
The case for staying put is just as concrete.
- The product is still finding its shape
- The system is simple enough that the premium would only slow the team
- Nobody on the team has built a microservices system before
Boundaries are the sticking point. Fowler’s Monolith First post (3 June 2015) says even experienced architects struggle to draw them early, and moving functionality between services is far harder than ordinary code refactoring inside one codebase.
The distributed monolith failure mode

Separate deployments do not make a system independent.
DORA’s test is a single question. What percentage of a service’s production deployments must be coordinated with releases of other services? DORA’s list of architecture pitfalls includes big-bang releases of many services at once, which take many hours or even days.
A Digital Frontiers engineering post (October 2019) documents the result. The team’s services had been cut badly, so every feature touched several of them and enum values were copied between services, and the fix was returning to a monolith.
The lesson they drew was that extracting a service from a monolith is far easier than gluing wrongly cut services back together.
Two documented reversals
Twilio Segment’s engineering blog (July 2018) reports consolidating over 140 services into one, after 3 full-time engineers were spending most of their time keeping the system alive.
Per-destination services had solved a real problem, head-of-line blocking in a shared queue. Then shared library versions diverged, each service had its own load pattern, and operational overhead grew with every added destination.
Shared library improvements went from 32 during the microservices era to 46 in the following year. Segment also listed what it gave up.
- Fault isolation, since one bad destination can crash the whole service
- Effective in-memory caching
- Safe dependency upgrades, which can now break several destinations at once
Istio did the same with its own control plane. Version 1.5, released in March 2020, folded the separate control plane services into one binary, istiod, and the project’s announcement called it embracing the monolith.
InfoQ’s report says the services had originally matched how Istio’s teams shipped on different schedules.
Where the sources disagree
The Dynatrace knowledge base (updated January 2026) calls microservices the de facto standard for modern software.
Fowler (June 2015) reports that almost every system he heard of that was built as microservices from scratch ended in serious trouble, and relays his colleagues’ argument that new projects should not start with microservices.
The gap is about defaults. Fowler calls his evidence sparse and his advice tentative, and he notes the counter-argument that starting with microservices builds the team’s rhythm of working with them.
The alternative: a modular monolith
Shopify Engineering (2019) describes one of the largest Ruby on Rails codebases, worked on for over a decade by more than a thousand developers.
By 2016 a small change could trigger a cascade of unrelated test failures. Shopify weighed microservices, expected a new set of problems, and chose a modular monolith. That meant one codebase with defined and respected boundaries between components, and no added deployment units.
How to Migrate From a Monolith to Microservices

Migrate incrementally with the strangler fig pattern. Put a proxy in front of the monolith, move one capability at a time into a new service, shift traffic to it, and retire the old code path once nothing depends on it.
Microsoft’s Azure Architecture Center and DORA both describe the pattern, and Fowler describes the same route as peeling services off at the edges.
Microsoft calls the intermediary a facade, which in practice is a reverse proxy sitting in front of the monolith.
- Check the monolith’s modularity. Fowler warns that most systems collect too many dependencies between modules to split sensibly, and the gradual successes he heard of started from good modular design.
- Pick the first capability. DORA looks for one that implements a single business function, interacts minimally with other services, and can be built, scaled and deployed alone.
- Put the facade in front. At first it routes every request to the monolith.
- Build the service with its own data. Microsoft’s database variant extracts the domain’s tables into an isolated database and retires the legacy tables after validation.
- Shift traffic gradually. With each iteration the facade sends more requests to the new service.
- Retire the old path. Remove the monolith code once no dependencies remain, then repeat for the next capability.
Give each extracted service its own deployment pipeline before it takes live traffic.
Where the strangler fig pattern stops working
Microsoft says the pattern is a poor fit when the system is small and simple to replace outright, or when the original solution has to be decommissioned quickly. It also fails if requests to the back end can’t be intercepted, or if the legacy system’s source code can’t be accessed or changed at some integration point.
The facade also needs watching. It must keep pace with the migration and must not become a single point of failure or a performance bottleneck.
Fowler describes other routes too. One is to replace the monolith entirely with a sacrificial architecture, worth building if it reaches the market quickly. Another is to start with a few coarse-grained services (he calls it a duolith) and split further as boundaries stabilize.
Peeling at the edges can also leave a substantial monolith at the center. Fowler accepts that outcome when most new development happens in the services and the monolith goes quiet.
Microservices FAQ
How big should a microservice be?
As large as one responsibility, not as small as a function. Microsoft warns that overly granular services add complexity and cost performance, and calls overly chatty traffic between two services a symptom of tight coupling.
Do microservices require containers and Kubernetes?
No. Fowler’s 2014 prerequisites ask for rapid provisioning, monitoring and fast deployment, not a specific platform. Containers on Kubernetes are the common way to meet them, and managed options such as Azure Container Apps handle orchestration for teams that do not want to run a cluster.
Can each microservice use a different programming language?
Yes. Java led in JetBrains’ 2022 survey, used by 34% of respondents building microservices, but nothing forces one stack. Microsoft still advises limiting the number of languages and frameworks, with shared standards for logging, monitoring and deployment.
How do teams test microservices without a shared test environment?
By isolating each service from its dependencies. DORA recommends test doubles such as mocks and stubs for external services, plus contract tests that confirm a service still meets its consumers’ expectations, so most testing runs on demand.
How should teams secure microservices?
Encrypt and authenticate every hop, and keep security out of the business code. Microsoft recommends mutual TLS between services, role-based access control and policy enforcement at the gateway, and lists token validation embedded inside each service as an antipattern.
Is a microservice the same thing as an API?
No. A microservice is the deployable service that owns a business capability and its data, while an API is the interface other services use to reach it. Microsoft notes that well-defined APIs keep a service’s internal implementation hidden.
How to Tell Whether Microservices Are Paying Off
They are paying off when a team deploys its service on demand, without another service releasing alongside it. DORA’s research on loosely coupled teams uses this as the test, and expects deployment frequency to rise and recovery time to fall as coupling drops.
Track these in order.
- Share of production deployments released together with other services
- Share of functional testing that runs without a shared integrated environment
- Deployment frequency, lead time, change failure rate and failed deployment recovery time, as trends
The first two numbers expose coupling directly. The four delivery metrics only show its results.
Record all six before the first extraction. The trade-off is that the split waits until the baseline exists.
If neither deployment frequency nor recovery time improves after the split, the coupling remains, whatever the service count. Position verified on October 29, 2026 against DORA guidance last updated October 20, 2025.
- What Communications Teams Should Ask Before Commissioning a Mobile App - November 12, 2026
- How to Install Node JS in VS Code and Run Your First Script - November 11, 2026
- Protecting Users and Brand Standards Across Image-Driven Platforms - November 10, 2026



