Coupling and Cohesion in Microservices

Priyal Walpita
9 min readApr 2, 2020


By Priyal Walpita

This article is going to examine a brief idea about microservices , how microservices are relevant to coupling and cohesion, exploring the meanings of coupling and cohesion and lastly the types of coupling.

Following are the main coupling patterns that will be described in this article.

  1. Implementation Coupling
  2. Temporal Coupling
  3. Domain Coupling


Microservices are individually deployable services based on a business environment. They interact with each other through networks, and as an architecture preference, they provide a range of options to solve the problems you can face. It follows that the architecture of microservices is based on a variety of interacting microservices.

They are a form of service — oriented architecture (SOA), one that is interpreted as to how service boundaries can be drawn, and that independent deployability is important. Microservices also have the advantage of being an agnostic platform.

From a technical point of view, microservices reveal the business functionality that they encapsulate from one or more network endpoints. Microservices interact with each other via these networks — rendering them a distributed system. They also encapsulate data storage and retrieval, display data, well-defined interfaces. So the databases are hidden within the service boundary.

Figure 1: Principles of well architected Microservices

If improperly architecture, an application based on microservices might end up being a distributed monolith. In such a program, microservices are chatty, sometimes calling each other. Changes to one microservice required changes to others. As well as developers work on the codebases of many microservices. There the microservices share the same database or even the code.

To solve these problems, one approach is to adapt domain — driven design. Restrict access using scoping rules. Use public APIs to encourage loose coupling. REST APIs shouldn’t be tightly coupled to specific applications or services. Effectively, the idea is to get the boundaries right towards high cohesion and low coupling.

If a microservice relies on the physical address of another service, then there’s tight location coupling. The service discovery tools can solve this. If a microservice needs to wait for another’s response, there’s temporal coupling. Therefore, a message bus or event stream can solve this.


The two forms of concepts Coupling and Cohesion have been used in computing for a long time, with the ideas first proposed by Larry Constantine in 1968 (a relatively auspicious year for computing) at the National Symposium on Modular Programming. Such twin concepts of Coupling and Cohesion went on to form the foundation of how much we thought of writing computer programs.

So, let’s go to a bit more deeper about Coupling and Cohesion.


The two concepts “Coupling” and “Cohesion” have been common when describing the boundaries of microservices. Coupling talks about how to change one thing needs a change in another, and cohesion talks about how we organize the code. These two terms have also been closely related.

By following the rule of Constantine, this relationship is well articulated:

A structure is stable if cohesion is high, and coupling is low.

(By Larry Constantine)

This has been a wise and valuable concept for Coupling and Cohesion. Ex: If we have two pieces of similarly connected code, cohesion is weak as the relevant functionality is scattered over both parts. We do have a strong coupling, because as this code changes, all items need to change.


Cohesion is the degree to which the members of a certain class belong together. It is a measure of how deeply each piece of device module functionality relates (Fenton and Bieman, 2014). Therefore, the most suitable term for defining cohesion is “the code that shifts together, stays together.” As we can see, strong cohesion makes thinking smoother and reduces dependency (Kramer and Kaindl, 2004). Low coupling is generally associated with strong stability (Kramer and Kaindl, 2004) (Jabangwe et al. 2015In microservices — oriented systems, a low degree of cohesion is accomplished by pooling specific business processes together, such that, if developers need to change actions, only a single microservice has to be modified (Newman, 2015).


Information Hiding , like dieting, is somewhat more easily described than done

(David Parnas, Secret History of Hiding Information)

Coupling is something that we should be careful of. The more issues are “coupled,” the more they tend to adjust together. So there are various forms of coupling for this, so different solutions that be needed for each type.

But, until we proceed to the various forms of coupling. Let’s describe the “Information Hiding” strategy in the coupling.


Implementation Coupling

It’s the most pervasive type of coupling. With implementation coupling, A is coupled to B where B is applied — as B changes are made, A also changes.

A typical and popular example of an implementation pairing is the sharing of a database. The Order Service provides a list of all orders issued in the system in Figure 1. The Recommendation Service offers our consumers with information that they would choose to buy on the basis of past transactions. Such results are automatically directly obtained from the database through the Recommendation Service.

Recommendations require information about which orders have been placed.

Examples To Show How Information Hiding Happens

If the Order service updates the name of the column, it breaks the Customer Order table apart, conceptually also providing order information, so will see if the Recommendation Service receives this information. It is easier to conceal the specifics of the implementation, as Figure 2 indicates that the Recommendation service has access to the information it wants through an API request.

We will also let the Order Service distribute a dataset in the form of a database that is meant to be used by consumers for bulk access. — Figure 3. Adding that the order service can publish data and any improvements made to the order service are invisible to customers because it retains a public contract.

The act of hiding a database behind a well-defined user interface helps the company to narrow the complexity of what is revealed and will allow us to alter how this data is interpreted.

Another trick that comes when describing a service interface that uses “outside — in” thought. That guides the service interface by first looking about problems from the point of view of the service consumers and then finding out how to execute the service contract.

Temporal Coupling

Temporal coupling is mainly a runtime problem that typically points to one of the main problems of synchronous call in a distributed setting. Meaning that when a message is received, and how the message is handled, it is connected in time, and we are supposed to have a temporary coupling.

Take a typical example to see this method

A synchronous HTTP request is made from the Warehouse service to the downstream Order service to get the correct order details. In order to fulfill the request, the Order Service must, in effect, retrieve the details from the Customer Service through a synchronous HTTP call. In order to achieve this overall process, the Warehouse, Order and Customer Services must all be up and contactable. They’re temporally bound together.

There are a variety of approaches to reduce this issue. We would use caching-if the Order Service stored the information it wanted from the Customer Service, then in certain situations the Order Service will be able to prevent a temporary connection to the downstream line.

The next thing we should suggest is the use of asynchronous transport to send messages, maybe anything like a message broker. This will then require the message to be transmitted to a downstream provider to make it accessible for the message to be handled.

Deployment Coupling

When we consider a single process, which consists of multiple statically linked modules. So, when a change is made to a single line of code in one of those modules, and there we should deploy that change. So, to do this we have to deploy the entire monolith including the modules that are unchanged. Therefore, everything should be deployed together, so we are using deployment coupling.

Deploying carries risk. There are lots of ways to reduce the risk of deployment, one is to change only what needs to be changed. If we can reduce the deployment coupling, perhaps like decomposing larger processes into independently deployable microservices, we can reduce the risk of each deployment by reducing the scope of the deployment.

Smaller releases are making for less risk. There is less to go wrong. If something goes wrong, working out what went wrong and how to fix is easier because only a small amount is changed less. And when reducing the size of the release makes fast feedback and release — on — demand methods. Smaller the scope of the release, the easier and safe it is to roll out, and the faster the feedback we get.

Reducing deployment coupling doesn’t require micro services. Runtimes like Erlang allow for the hot deployment of new versions of modules into a running process.

Domain Coupling

There must be some contact with participants in a system composed of several independent services. Thus, in a microservice architecture, domain coupling is the result — interactions between services are model interactions in our actual domain.

To give a specific example, consider Music Corp. There’s a shop in there that sells products. When consumers place orders for CDs, staff working in the warehouse need to consider what items need to be selected and packed and where the shipment needs to be shipped. The information on the order must then be exchanged with the people who work in the warehouse.

Figure 5 illustrates this feature — the Order Processing service sends all the specifics of the shipment to the Warehouse department, which then releases the object to be packed. As part of the process, however, the Warehouse company uses the customer ID to gather customer information from the Customer Service. And then we know how to alert them when the order is sent out.

But in this case, we share the whole order with the warehouse, which makes little sense — because the warehouse just wants information on what to load and where to deliver it.

And the issues with information that we use to monitor access to be exchanged so easily — if the full order is exchanged, we might end up revealing credit card data to providers that do not need it.

Ex :

Instead, we’ll come up with a new Pick Instruction domain definition that includes all the Warehouse service requires detail, as you’ll see in Figure 6. Another example of hiding information.

Coupling can be further minimized by reducing the need for a Warehouse service, so if you need to learn about a client, we will then include all the necessary information through the Pick Instruction, as seen in Figure 7.

However, there is a issue for this solution to figure out, which assumes that at some stage Order Processing would have access to the Customer Service in order to be able to produce the Pick Instruction, although it is possible that Order Processing will also continue to have access to customer information for certain purposes, and that is unlikely to be a concern..

As a consequence, there is an alternative solution where Order Processing produces some kind of event that the Warehouse absorbs, seen in Figure 8. The mechanism operates like this — Order Processing relies on the Warehouse service to ensure that the shipment is delivered to the Warehouse to respond to activities from the Order Processing service.

We have elaborated the coupling and cohesion in microservices and described the main 3 patterns of coupling. Thanks for reading this article.



Priyal Walpita

CTO @ ZorroSign | Seasoned Software Architect | Expertise in AI/ML , Blockchain , Distributed Systems and IoT | Lecturer | Speaker | Blogger