Top Microservices Design Patterns for Your business

Using microservices for building apps is rapidly gaining popularity as they can bring so many different benefits to the business: they are safe and reliable, scalable, optimize the development time and cost, and are simple to deploy.

In our previous articles, we discussed the best tools to manage microservices, the advantages and disadvantages of using microservices and the differences they have with monolith architecture, and hexagonal architecture.

Despite multiple benefits, app development with microservices has many challenges:

  • Managing shared access
  • Data consistency
  • Security of services
  • Communication between services
  • Dependency management

However, using the correct microservices design patterns can overcome the challenges mentioned above and even maximize performance. There are actually many benefits the patterns can bring to your business, but remember that design patterns are not "one-size-fits-all" solutions. Thus, pay attention to the advantages and disadvantages of each pattern and when to use them so that the implementation would be beneficial for your goals.

And now, let us provide you with our favorite microservices design patterns and things to pay attention to before implementation:

Strangler pattern

The strangler pattern can be an excellent solution if your goal is moving incremental existing Monolithic applications to Microservices. Such a procedure can be challenging as it may disrupt the application's availability, but using the Strangler pattern can minimize such risks.

Let us explain to you how it works: basically, it allows a Monolithic application to migrate to Microservice Architecture by gradually replacing specific functionality with new Microservices. After this, the new application system replaces all features from the previous system.



Now that we know how this pattern works, let's understand what the advantages and disadvantages of the Strangler pattern are.


  • Allows for safe migration of Monolithic applications to Microservices.
  • It can be used for versioning of APIs.
  • It enables the old services to remain for solutions that are not upgraded.
  • The migration process and new functionality development can be run simultaneously.
  • This pattern is easy to implement
  • The development effort required to rewrite the entire application is lower than in other approaches
  • Works well even when refactoring a complex system.


  • Routing and network management require a lot of ongoing attention.
  • Adding an API gateway can increase the latency of the system.
  • You will need a rollback plan for each refactored instance.
  • End-to-end testing becomes difficult.

When to use the Strangler pattern

  • For incremental migration of a large Backend Monolithic application to Microservices.

When not to use

  • If the Monolith is small and not complex, the wholesale replacement can be a better option for you.

Saga pattern

Saga pattern helps establish consistency in distributed applications and coordinates and manages transactions between multiple microservices to maintain data consistency. This pattern was developed in 1987 and is considered to be one of the oldest patterns, and was designed as a conceptual alternative for long-running database transactions in SQL databases. And now, in the modern context, this pattern is widely used for distributed transactions as well.

How does it work? Each transaction is followed by an event that triggers the next transaction step, and, in case the local transaction fails, Saga executes a rollback transaction compensating for the failure. Basically, to undo the preceding local transactions' changes.

You can see this process in the picture below.


Znimok_ekrana_2023_05_01_o_18_25_23_06ff41a93e.png Znimok_ekrana_2023_05_01_o_17_31_18_515e1d7019.png Saga_3_6bec94856b.png

There are many ways to implement the SAGA algorithm, but these 2 are the most popular: Events/Choreography: here, the Microservices are responsible for the creation of new events after completing their local transaction. Decentralized co-ordinations where each Microservice produces and listens to other Microservice's events/messages and decides if an action should be taken or not.

Command / Orchestration: an orchestrator (arranger) manages all the transactions and directs services to execute local transactions. Basically, this orchestrator communicates with the other services and commands them what to do and when. Such communication takes place in a command mode.

Now, let's discuss the advantages and disadvantages of this pattern.


  • Does not require the implementation of additional service and maintenance.
  • Since all the responsibilities are distributed across the saga participants, it doesn't introduce a single point of failure.
  • Provides consistency via transactions in Microservice Architecture where NoSQL databases without 2PC support are used.


  • Need to handle transient failures.
  • The debugging process can be a challenge. Moreover, the complexity of the whole system grows all the time as the number of Microservices increases.
  • There is also a need to develop compensating transactions.

When to use the Saga pattern

  • In systems where are used distributed NoSQL databases.
  • In Microservice Architecture, that is highly scalable and loosely coupled and where the event sourcing is used.

When not to use Saga

  • In lowly scalable transactional systems where SQL Databases are used.
  • In systems where cyclic dependency exists among services.

Aggregator pattern

The Aggregator pattern is a service that receives a request from the client or API Gateways, and, after that, it makes requests of multiple services, and then, it combines the results and responds back to the initiating request in 1 response structure.



And for now, let's discuss the main advantages and disadvantages of the aggregator pattern.


  • It reduces chattiness and communication overhead between the client and services.
  • Is easy to understand and implement
  • Allows for architecturally easily understood endpoint consolidation of discrete functionality.


  • It can reduce availability because of the multiplicative effect of failure.
  • Increases the latency of responses.
  • The complexity of troubleshooting is quite high and can be increased, thus, there will be a need for additional time to restore service and repair faults.
  • Not highly scalable

When to use the Aggregator Pattern

  • When you have lower-scale needs and business value.
  • Where there is a high failure rate of distant third-party calls.

When not to use the Aggregator Pattern

  • When you have high scalability needs
  • When you have high availability needs.
  • If you need to deploy the pattern for solutions that comprise significant business value.

Event Sourcing

In practice, event sourcing requires careful management of the event store, which contains the history of all events in the system. This includes ensuring the durability and reliability of the event store, as well as managing the performance and scalability of the system as it grows.

Overall, event sourcing is a powerful pattern for building scalable, maintainable, and reliable microservices-based systems, but it requires a deep understanding of the underlying principles and practices to implement it effectively.

04_6474d00f3f.png eevnt_sourcing_5f5171f07c.png

Let us provide you with the advantages and disadvantages of the Event sourcing pattern.


  • Provides atomicity to highly scalable systems.
  • Enables automatic history of the entities, including time travel functionality.


  • The challenges can occur with reading entities from the Event store, and usually, an additional data store (e.g., CQRS pattern) is needed.
  • The complexity of the system is increasing all the time, and you may need a domain-driven design.
  • Migrating the Schema of events can become challenging.
  • The system needs to handle duplicate events.

When to use Event Sourcing

  • It is perfect for highly scalable transactional systems with SQL Databases.
  • Typical Message Driven or Event-Driven systems.
  • For transactional systems with NoSQL Databases.
  • Highly scalable and highly resilient Microservice Architecture.

When not to use Event Sourcing

  • Lowly scalable transactional systems.
  • In simple Microservice Architecture, where Microservices can exchange data synchronously.

Command Query Responsibility Segregation (CQRS)

CQRS, as a design pattern, basically treats retrieving data and changing data differently. Command Query Responsibility Segregation simplifies the query process and hides complex, multi-system changes by using command handlers. This design pattern was created to ensure that a method working with data is only allowed to perform one of two tasks: to retrieve the data or modify it. But it can not do both.

05_11b39be563.png CQRS_9f72db23fd.png Znimok_ekrana_2023_05_01_o_18_40_03_20245a6f41.png Znimok_ekrana_2023_05_01_o_18_41_21_ee48573d8f.png

The advantages and disadvantages of this system are the following:


  • Independent scaling.
  • Simpler queries.
  • Optimized data schemas.
  • High availability of the data.
  • Separation of concerns.


  • Read data store is weakly consistent (eventual consistency)
  • Supporting this pattern requires expertise in a variety of database technologies. Moreover, the overall complexity of the system is increasing all the time.

When to use CQRS

  • In highly scalable Microservice Architecture, especially when using event sourcing.
  • In a collaborative domain where many users access the same data in parallel.
  • Systems are expected to evolve over time and might contain multiple versions of the model.

When not to use CQRS

  • In Microservice Architecture, with the insignificant volume of events.
  • In systems where read and write operations have a similar load.

Backends for Frontends (BFF)

It is a well-known fact that usually, the Frontend and the Backend applications are decoupled and separate services, especially when we are talking about Microservice Architecture. The problems occur when there is a need to use the same backend Microservice for both the Web and the Mobile clients, as the requirements of those two systems are completely different.

, Backends for frontend patterns can become an excellent solution that could be used in scenarios where each UI gets a separate backend customized for the specific UI. Furthermore, it has multiple advantages.

06_97ee42ecc4.png Znimok_ekrana_2023_05_01_o_18_46_58_12a28ba0fb.png Znimok_ekrana_2023_05_01_o_18_49_28_c0b7e570a9.png

Let us provide you with the main advantages in more detail.

  • Acts as a Facade for downstream Microservices ( and, thus, reduces the chatty communication between the UI and downstream Microservices)
  • It can be used to provide higher security.
  • Allows to provide less chatty communication between the UIs and downstream Microservices.


  • The problem of code duplication among BFFs can occur.
  • The proliferation of BFFs in case many other UI's are used (Web, Mobile, Desktop, Smart Watches, Smart TV, etc.).
  • There is a need for careful design and implementation.

When to use Backends for Frontends

  • When your app has multiple UIs that have different API requirements.
  • When Micro-frontends are used in UI development.
  • When there is a need for an extra layer between the UI and Downstream Microservices for Security reasons.

When not to use Backends for Frontends

  • When the application has multiple UI, but they consume the same API.
  • When Core Microservices are not deployed in DMZ.


In the modern software development process, Microservice Architecture can provide long-term benefits. But, keep in mind that Microservice Architecture can not be used in every use case. If such technology is implemented incorrectly or in the wrong system, Microservice Architecture can cause more problems than bring you benefits. Thus, it is better to delegate this complex process to professionals who will follow a set of best practices and find a custom solution for you.