Microservices

On this page 7

Microservices is a software architecture style in which an application is built as a set of small, independently deployable services, each responsible for one business capability, running in its own process and communicating over the network. In software architecture, it stands opposite the monolith, where all functionality is built and released as one unit.

Each service owns its data and its release cycle, so a team can change, test and deploy it without coordinating a release of the whole system. This independence is the central benefit of microservices, and the network, data consistency and operational complexity it introduces are its central costs.

How a microservices architecture works

A microservices system divides the domain along business boundaries, often called bounded contexts in domain-driven design, rather than along technical layers. An online store might have separate services for catalog, cart, ordering, payment and shipping, each with its own code base, database and deployment pipeline.

Services communicate through well-defined APIs. Synchronous calls typically use HTTP with REST or gRPC, while asynchronous messaging through a broker such as Kafka or RabbitMQ lets services react to events without waiting for each other. An API gateway usually sits at the edge, routing external requests and handling concerns such as authentication and rate limiting.

Running many services requires supporting infrastructure: service discovery so that services can find each other, containers and an orchestrator such as Kubernetes for deployment and scaling, and centralized logging, metrics and distributed tracing to follow a request across service boundaries.

Core principles and their parameters

Several principles distinguish genuine microservices from a system that is merely split into pieces. The table summarizes them and the practical choices each involves.

PrincipleMeaningPractical consequence
Independent deployabilityA service ships without releasing othersBackward-compatible API changes are mandatory
Database per serviceNo shared tables between servicesCross-service queries need APIs or events
Single business capabilityOne service, one responsibilityService boundaries follow the domain
Decentralized governanceTeams choose suitable toolsPlatform standards limit sprawl
Design for failureAny call may time out or failTimeouts, retries and circuit breakers
Team ownershipOne team owns a service end to endTeam size often 5 to 9 people
Principles of microservices and what they mean in practice

Service size is not measured in lines of code. A useful test is whether one team can understand, change and redeploy the service confidently within a short cycle; services that always change together are probably one service split too finely.

Microservices compared with other architectures

Microservices are one point on a spectrum of modularity and deployment granularity. The comparison below shows why many teams start with a well-structured monolith and extract services only when needed.

AspectMonolithModular monolithMicroservicesServerless functions
Deployment unitWhole applicationWhole applicationEach serviceEach function
Module boundariesOften weakEnforced in codeEnforced by networkEnforced by platform
Data consistencyLocal transactionsLocal transactionsEventual consistencyEventual consistency
Operational effortLowLowHighMedium, platform-managed
Independent scalingNoNoYesYes, automatic
Best fitSmall teams, early productsGrowing productsMany teams, large domainsEvent-driven tasks
Microservices and neighboring architecture styles

Microservices are compatible with internal design approaches such as clean architecture and patterns such as dependency injection, which structure the code inside each service. The architecture style decides how the system is divided and deployed; those patterns decide how each part is organized internally.

When microservices are the right choice

Microservices pay off when organizational scale, not technical fashion, drives the decision. Conway’s law observes that system structure tends to mirror the communication structure of the organization, so the architecture works best when service boundaries match team boundaries.

SituationRecommendationReason
Single small team, new productModular monolithBoundaries are still changing
Several teams blocked by shared releasesExtract servicesRestores independent delivery
One component needs very different scalingExtract that componentScale only where needed
Strong need for cross-entity transactionsKeep togetherDistributed transactions are costly
No automated deployment or monitoringBuild the platform firstMany services multiply manual work
Decision guide for adopting microservices

Migration from a monolith is usually incremental through the strangler fig pattern: new functionality and extracted capabilities are routed to services one at a time, while the monolith shrinks. A big-bang rewrite carries far more risk and rarely succeeds on schedule.

Risks and common mistakes

The most frequent failure is the distributed monolith: services that are deployed separately but must be released together because they share databases, libraries with business logic or tightly coupled synchronous calls. It combines the costs of both styles with the benefits of neither.

  • Chatty synchronous chains: a request passing through five services multiplies latency and failure probability.
  • Shared database: breaks independent deployment and hides coupling.
  • Missing observability: without tracing, finding the cause of one slow request becomes guesswork.
  • Ignoring data consistency: business processes spanning services need sagas or compensating actions instead of distributed locks.
  • Premature splitting: boundaries drawn before the domain is understood are expensive to move later.

Each network call adds latency, typically around a millisecond or more within a data center, plus a chance of failure. Designs that favor asynchronous events and keep critical paths short remain resilient as the number of services grows.

In simple terms

Microservices means building one large application out of many small, separate programs that talk to each other. Each small program does one job, such as handling payments or showing products, and a dedicated team looks after it.

Compare a single large restaurant kitchen with a food hall. In the kitchen, everyone shares one space, so a problem at one station slows everyone. In a food hall, each stall runs on its own, can change its menu without asking the others and can stay open if a neighbor closes. The price is more coordination, because orders, deliveries and cleaning must now work across many independent stalls.

A practical example

A ticket-selling platform starts as a single application maintained by eight developers. After a few years, the company has about 60 engineers in seven teams, and every weekly release requires coordinating changes from all teams. A bug in the reporting module once delayed an urgent fix to checkout by several days.

The company extracts services gradually using the strangler fig pattern. Checkout and payment become the first services, each with its own database, followed by event search and notifications. When a large concert goes on sale, the checkout service scales to many more instances while the rest of the system stays unchanged.

After roughly a year, teams deploy their services several times a day without joint release meetings. The company also adds distributed tracing and a platform team, because diagnosing failures across ten services proved impossible without them. The outcome is faster delivery at the cost of higher operational effort, which the company considers worthwhile at its size.