Home Microservices Patterns Scalability Strategies Monitoring Frameworks Infrastructure Tuning Performance Patterns Architecture Comparison Optimization Comparison About Contact
Reference · Microservices

Microservices Architecture Patterns

Structural and communication patterns for designing, deploying, and coordinating independently deployable services in distributed platform architectures.

Articles published on this website summarize publicly available information, industry research and educational materials.

Decomposition Patterns

Decomposition patterns address how a service boundary is defined and what scope of functionality a single microservice should own. The primary approaches are decomposition by business capability and decomposition by subdomain.

Decompose by Business Capability

This approach aligns service boundaries with organizational business capabilities — discrete areas of business functionality such as order management, inventory, or customer notification. Each service owns the data and logic for its capability area. The advantage is that service boundaries remain stable even as implementation details change, because business capabilities change less frequently than technical implementations.

Decompose by Subdomain

Domain-Driven Design's subdomain concept provides a more rigorous basis for service boundary definition. Core subdomains — areas where the business has competitive differentiation — warrant well-defined service isolation. Supporting and generic subdomains are candidates for simpler implementations or third-party services. This approach requires investment in domain modeling before service decomposition begins.

Strangler Fig Pattern

For teams migrating from a monolithic application, the strangler fig pattern describes incrementally replacing specific functionality with microservices without a full rewrite. A routing layer directs requests to either the monolith or the replacement service depending on which paths have been migrated. The monolith is progressively replaced until the original application can be retired.

Communication Patterns

Microservices communicate using either synchronous or asynchronous mechanisms. The choice affects coupling, latency characteristics, and failure mode behavior.

Synchronous Request-Response (REST / gRPC)

REST over HTTP remains the most common synchronous communication mechanism for microservices. REST is language-agnostic, well-supported by infrastructure tooling, and straightforward to debug. gRPC, using Protocol Buffers over HTTP/2, offers lower overhead and built-in schema definition, making it suitable for high-throughput internal service communication where the performance overhead of REST is material.

Asynchronous Messaging

Message queues and publish-subscribe systems decouple service implementations by removing the requirement for the producer and consumer to be available simultaneously. Event-driven patterns using message brokers improve fault isolation — a consumer failure does not propagate back to the producer — and enable fan-out to multiple consumers from a single producer. The primary complexity is in ensuring message delivery semantics (at-least-once vs. exactly-once) match the requirements of the consuming service.

API Gateway Patterns

An API gateway provides a single entry point for external traffic, handling concerns that apply across multiple services — authentication, rate limiting, request routing, and protocol translation — in one place rather than repeating them in each service.

Backend for Frontend (BFF)

The BFF pattern creates separate gateway instances for distinct client types, such as a mobile BFF and a web BFF. Each BFF aggregates data from multiple downstream services and shapes the response for its specific client's needs. This avoids the complexity of building a single gateway that attempts to serve very different client requirements simultaneously.

Data Management Patterns

Managing data in a microservices architecture involves decisions about service data ownership, data consistency across service boundaries, and query patterns that span multiple services.

Database per Service

The database-per-service pattern assigns each microservice its own data store, ensuring services are decoupled at the persistence layer. Services cannot access each other's databases directly; data sharing occurs through service APIs. The trade-off is that queries requiring data from multiple services cannot be handled with a single database query and must instead aggregate data through service calls or a query service.

Saga Pattern

The saga pattern manages distributed transactions across multiple services without using distributed ACID transactions. A saga is a sequence of local transactions, where each transaction publishes an event or message that triggers the next step. Compensating transactions handle failure states by reversing the effects of completed steps. Sagas can be orchestrated by a central coordinator or implemented as a choreography where each service reacts to events from other services.

CQRS

Command Query Responsibility Segregation separates read and write operations into distinct models. Write operations (commands) update the domain state; read operations (queries) retrieve data from a read-optimized projection. CQRS enables independent scaling of read and write paths and allows the read model to be shaped specifically for query requirements rather than constrained by the write model's normalization requirements.

Resilience Patterns

Resilience patterns prevent failures in one service from cascading to others and allow services to degrade gracefully under load or when dependencies are unavailable.

Circuit Breaker

The circuit breaker pattern wraps calls to external services with state-aware logic that stops sending requests to a failing dependency once a failure threshold is reached. The circuit remains open for a configurable interval, then transitions to a half-open state where a limited number of test requests determine whether the dependency has recovered before full traffic is restored.

Bulkhead

The bulkhead pattern isolates resource pools — thread pools, connection pools, or process instances — by consumer or service. A failure that exhausts the resource pool for one service does not affect resources allocated to other services. Named after ship compartmentalization, this pattern limits the blast radius of service degradation.

Service Mesh Patterns

A service mesh moves cross-cutting communication concerns — mutual TLS, traffic management, retries, circuit breaking, and observability — into a dedicated infrastructure layer rather than implementing them in application code. A sidecar proxy running alongside each service handles the mesh functions transparently.

Service mesh adoption involves significant operational overhead in deployment and configuration management. The pattern is most appropriate for organizations operating at a scale where managing service communication concerns in application code has become a maintenance burden, or where consistent enforcement of security and observability policies across many services is a priority.