Decoupled Microservices Architecture with Materialize

Created January 31, 2022


There are several ways to handle data in a microservice architecture, in this article we will cover the approach of having a separate database for each microservice.


This article will build upon the concepts covered in the following video by Houssem Dellai:

Architecture overview

We will use the following architecture as described in the video above. The following diagram shows the architecture:

Data in Microservices architecture

Quick overview of the architecture:

The problem with the above architecture is that the Basket service is tightly coupled with the Catalog service. There are a few drawbacks to this architecture:

To decouple the microservices, we will use a third microservice called Gateway. This microservice will be responsible for routing the requests to the other microservices. But with this approach, the API Gateway will handle all the requests and the microservices and this could turn into a bottleneck as it will have a lot of responsibilities.

Let's take a look at another approach to decouple the microservices.

Loosely coupled microservices

As each microservice is independent and owns its own data, to decouple the microservices, we can use a materialized view that will store the aggregated data of the microservices.

The following diagram shows the architecture with the materialized view:

Loosly coupled microservices

Quick overview of the architecture above:

The downsides of this approach are:

Using Materialize

Materialize is a streaming database that takes data coming from different sources like Kafka, PostgreSQL, S3 buckets, and more and allows users to write views that aggregate/materialize that data and let you query those views using pure SQL.

Unlike traditional materialized views, Materialize is designed to maintain the data in a continuous state and keeps the views incrementally updated. This means that if you have a view that is constantly updating, you can query the data in real-time. A normal materialized view would do a full table scan every time it needs to be updated which can be very expensive.

For a more detailed explanation of Materialize, please see the Materialize Documentation.

You can also take a look at this quick video that explains what Materialize is.

Decoupled Microservices Architecture with Materialize

Thanks to Materialize, we can decouple the microservices architecture and use a live materialized view to store the aggregated data. Materialize will keep the materialized view incrementally updated and will allow us to query the data in real-time with subsecond latency.

This will eliminate the need for the event-driven architecture and will also eliminate the need for extending the Catalog service to send change events to the Basket service.

The following diagram shows the architecture with Materialize:

Decoupled Microservices Architecture with Materialize

Quick overview of the architecture using Materialize:

As Materialize is Postgres wire-compatible, we don't need to use any third-party libraries to use Materialize and there is no learning curve.

One thing that you need to keep in mind is that as of the time being, Materialize does not have persistence. This means that if you restart the service, the materialized view will need to re-aggregate the data. This feature is on our roadmap and will be available soon.


To put this into practice, you can take a look and run the following demo:


Useful links: