Skip to content

Eventual Consistency in Microservice Architecture

Daten in Microservices teilen

Don’t be afraid of redundancy. Sharing data correctly in microservices.

TL;DR: To get the full benefit from the use of microservices, they must be completely decoupled. This decoupling scares many developers, as they suddenly have to deal with eventual consistency. However, there are ways to deal with this.

At OOP 2024, a presentation by Lars Röwekamp focused on a point that can lead to serious problems in the day-to-day work of architects: eventual consistency in microservices.

At first glance, eventual consistency always seems like the biggest problem to contend with when using microservices: “Times of around one second between the creation of data and its correct display in the UI? This is unacceptable for my users!” But is it really? According to Lars Röwekamp, users are used to non-transactional behavior. Even a bank transaction, which already has the word “transaction” in its name, is not transactional in the sense of a database transaction. This means that the money is not debited from the payer’s account and deposited into the payee’s account at the same time. A few days can pass in between. This is because the bank earns its money with precisely these days by investing the transfer amount with a good return.

However, if it is important to the customer or user that the UI is displayed correctly, the microservice, which in this case acts as the data owner, can return the created data so that the frontend can display it.

How do I share data in microservices in a secure and user-friendly way?

Here is an example of microservice data replication in an online store: Assume there are the two microservices “Addresses” and “Checkout”.

  1. The user can maintain delivery and billing addresses via the “Addresses” service. They can also define a default address in each case.
  2. The “Checkout” microservice stores the standard addresses redundantly. These are sent to the user via a domain event via an event bus.

Now the user would like to change their default delivery address during the order process. So he performs the necessary operations in the UI. This sends a request containing the new location address to the “Addresses” service. However, before the change has been propagated to the “checkout” service via the event bus, the user is already redirected to the order summary page.

It would be bad if the old address was displayed there. The user would then believe that their change had no effect. To avoid this, the previously selected address could be displayed directly in the UI – even if the “Checkout” service doesn’t even know it yet.

Risk: What happens if the domain event is lost, and the “Checkout” service therefore still has the old default address when the order is sent?

Solution: To avoid this, the UI can send the desired address when the order is sent. The “Checkout” service can then compare the two addresses before processing the order and issue an error message if the data does not match.