In the world of microservice architecture, we build out an application via a collection of services. Each service in the collection tends to meet the following criteria:

  • Loosely coupled
  • Maintainable and testable
  • Can be independently deployed

Each service in a microservice architecture solves a business problem in the application, or at least supports one. A single team is responsible and accountable for one or more services in the application.

Microservice architectures can unlock a number of different benefits.

  • They are often easier to build and maintain
  • Services are organized around business problems
  • They increase productivity and speed
  • They encourage autonomous, independent teams

These benefits are a big reason microservices are increasing in popularity. But potholes exist that can derail all these benefits. Hit those and you’ll get an architecture that amounts to nothing more than distributed technical debt.

Communication between microservices is one such pothole that can wreak havoc if not considered ahead of time.

The goal of this architecture is to create loosely coupled services, and communication plays a key role in achieving that. In this article, we are going to focus on three ways that services can communicate in a microservice architecture. Each one, as we are going to see, comes with its own benefits and tradeoffs.

HTTP communication:

The outright leader when choosing how services will communicate with each other tends to be HTTP. In fact, we could make a case that all communication channels derive from this one. But, setting that aside, HTTP calls between services is a viable option for service-to-service communication.

If there are two services in the architecture. ServiceA might process a request and call ServiceB to get another piece of information.

What we have here is synchronous HTTP calls between the two services. This is a viable communication pattern, but it does create coupling between the two services which is likely not needed.

Using asynchronous communication will allow the services to remain loosely coupled from one another.

By transforming the communication between the two services from synchronous to asynchronous – the first service is no longer stuck waiting for the second service to complete before returning from its work.

With this approach, you can keep the services isolated from one another, and the coupling is loose. The downside is that it creates extra HTTP requests on the second service; it is now going to be polled from the outside until the request is completed. This introduces complexity on the client as well since it now must check the progress of the request.

Message communication:

Another communication pattern we can leverage in a microservice architecture is message-based communication.

Unlike HTTP communication, the services involved do not directly communicate with each other. Instead, the services push messages to a message broker that other services subscribe to. This eliminates a lot of complexity associated with HTTP communication.

It doesn’t require services to know how to talk to one another; it removes the need for services to call each other directly. Instead, all services know of a message broker, and they push messages to that broker. Other services can choose to subscribe to the messages in the broker that they care about. There will still be some coupling between the two services using this pattern.

Event-driven communication:

The final communication pattern we will visit in this post is the event-driven pattern. This is another asynchronous approach, and it looks to remove the coupling between services altogether.

Unlike the messaging pattern where the services must know of a common message structure, an event-driven approach doesn’t need this. Communication between services takes place via events that individual services produce.

A message broker is still needed here since individual services will write their events to it. But, unlike the message approach, the consuming services don’t need to know the details of the event; they react to the occurrence of the event, not the message the event may or may not deliver.

In formal terms, this is often referred to as “event only-driven communication.”

This pattern keeps services loosely coupled as no payloads are included in the event. Each service in this approach reacts to the occurrence of an event to run its business logic.


There are more ways for services to communicate both in a synchronous and asynchronous pattern.

But, these three highlight the advantages and disadvantages of favoring synchronous versus asynchronous. There are coupling considerations to take into account when choosing one over the other, but there are also the development and debugging considerations to factor in as well.


Leave a Reply