9 Most Common Mistakes when Migrating from Monolith to Microservices

Tags
2 June 2022
Complete Guide for CTO & IT Directors
Microservices under X-Ray Three books image Download free ebook

With the microservices architecture gaining a lot of traction in the software world, more and more companies are migrating from their existing monolith to microservices architecture. Typically, this is a wise move, but great care needs to be taken in order to complete this process successfully. Below, we have gathered the nine most common issues we see when working with our customers on monolith to microservices migration.

1. Having nothing to migrate from 

While in some specific systems it might make sense to start development with a microservice architecture, typically it is better to start off with a monolith with well-defined module boundaries and migrate to microservices when the product is more mature. During early development, the approach, requirements, and designs shift a lot. Plus, based on market response, product managers might decide to pursue a different market or niche. Additionally, decision-makers frequently do not have a complete understanding of the requirements from the beginning of the project.

A microservices architecture, due to its distributed and loosely coupled nature, makes introducing system-wide changes much harder than with a monolith. Such groundbreaking changes need to be synchronized across the team and across each microservice. More development effort is required to implement the changes in the code and modify APIs used between services. It can take a lot of time for the system to stabilize after such a migration.

To better understand if your company is ready to migrate to microservices, take a look at this article. It expands on this section with a deeper explanation of who should consider migrating to microservices.

2. Not defining clear objectives and timeline for migration

In larger organizations (those with more than 10 or 20 employees), things tend to fall through the cracks if not managed and tracked against goals. This is particularly true in the case of refactoring initiatives: there is always more immediately pressing work to do than dealing with technical debt and making non-functional changes. Therefore, it is very important to define a strategy and determine precise goals for the microservices migration effort.

The product managers and other stakeholders, when provided a clear plan and goals to achieve, will be able to navigate large numbers of customer requests and issues that come up along the way to accomplish the goals laid out ahead of time. Even if the migration does not go completely to plan (which is quite likely), setting out objectives beforehand is still helpful in getting an idea of where the company is, where it needs to go, and what resources will be required. If the project was not completed in the original timeframe, project managers will ask questions and execute corrective actions to get back on track. 

On the other hand, if the migration effort has no concrete scope or timeline, it will be much easier to push back important tasks into the undefined future when the team will have more time and fewer paying customer requests. Unfortunately, this is a shortsighted approach: if the system were fulfilling customer expectations, the microservices migration would not be needed in the first place. In this case, the migration is needed to better serve customers, and a faster migration to microservices is better for the overall business. 

3. Not enough (or too much) planning

In addition to the goals and timelines mentioned in the previous section, in order to be able to reach goals in a timely manner, a plan needs to be developed, including the technology side (e.g. technology stack, platform services, tools, etc.), organizational considerations (team organization, project management methodology), and functional analysis (what needs to be migrated, what has the most priority, what changes make sense to introduce in the migration process).

Keep in mind the plan cannot be too detailed–the planning process itself should not require inordinate time and many possibilities cannot be planned for adequately in the fast-paced market. Companies need to keep migration plans on a level that allows them to estimate key milestones and deliverables (e.g. specific microservices deployment) but plans should also be flexible so that changes can be made as the process move along.

If you want to learn more about how to develop an optimal plan to scale your product with microservices, you will find this article interesting.

4. No unified approach to microservices platform

Even though the microservices architecture is all about decoupling and decentralization, some amount of standardization, especially if developed early in the migration process, can be very beneficial. The obvious advantage is that the work related to designing and implementing common services like logging, metrics, health checks, and testing can be done once and then reused by multiple teams. Also, in the short-term, it is easier to move developers across teams or train new ones if requirements change when standards are kept between microservices.

In the long term, some teams can decide to move away from the common tooling. For close to 90% of the teams, the standard setup should be enough to allow them to work effectively. In case of any divergence from the standard, the cost of developing and maintaining the fork should also be taken into account, which might offset the potential efficiency gains.

5. Very tight coupling of services

One common error in the microservices architecture design is applying design patterns of the monolith to microservices platform. While those patterns could work, they will prevent the company from taking full advantage of the resilience of microservices.

For example, I have seen examples of companies implementing a form of distributed three-phase commit transactions across their microservices ecosystem. In this scenario, changes made to the underlying data models are not made permanent until all microservices taking part in the transaction confirm successful execution. While this approach ensures data consistency and immediate failure feedback, it requires that all services are operational, in a healthy state, and not experiencing overload. Conversely, if any of these issues affects one of the microservices (even if it is not critical for the transaction), the whole system might be rendered nonoperational and immediate intervention will be needed to bring it back to order.

If the transaction were implemented as a series of separate operations on microservices, the transaction might be partially completed even if one of the components could not complete its task. In addition, if the issue is permanent, and the transaction cannot be fulfilled at all, a series of compensating actions should be issued to bring the system to the original state.

6. Relying too much on synchronous communication between microservices

One of the key factors that increases the resiliency of any microservices-based system is favoring asynchronous communication over synchronous communication. Synchronous communication is typically a remote procedure call from one service to the other one, like fetching some data from a RESTful endpoint or causing something to occur with a gRPC endpoint. It requires both services to be up and running at the time of the call and it generally also keeps the calling microservice waiting for the result or confirmation of the action being performed. This increases requirements on both the availability and the computing resources of the platform hosting the microservices.

An asynchronous communication channel is most often a message sent by means of a message broker platform to a specific channel. The message broker assures that the messages are durable and are delivered to the microservices subscribed to listen to them. The consumer microservice, upon receiving the message, can act on it and also send a follow-up message or a response back using the same means. This setup differs from synchronous communication in that it puts less strict requirements on the underlying platform: the microservices do not need to be up and running at the same time (the consumer can catch up on the messages later on when it is back online).

Also, the hardware requirements are less demanding: the sender microservice thread is not blocked; when the confirmation or response comes as a message, it will be picked up in the same way as all other communication. Also, if there is a load spike on the service, the incoming messages will just queue up on the channel, instead of resulting in connection timeouts or failures. Moreover, in case of a spike, it is much easier and faster to scale up the consumers by just launching additional instances to process the excess messages in the queue instead of setting up load balancers and reconfiguring the backend instances.

However, there are types of communication in the microservices system that do not play well with asynchronous calls. Those include calls that require immediate feedback to the user (e.g., search as you type or real-time user action feedback) and calls whose main purpose is to return data. Converting those calls to asynchronous does not bring any benefits, i.e., the queuing of the message of a call requiring real-time feedback does not help. Moreover, it introduces additional overhead related to message processing and increased complexity that would affect maintenance effort.

7. Increasing complexity too much by writing too many microservices

While one of the basic principles for microservice system design is “single responsibility”, as in “design your microservices so that one microservice is responsible for a single thing”, it is often applied in an excessively narrow way. 

Systems of a mid-level complexity will quite often grow to hundreds of microservices within the first year of development. Each concept, data model, and small groups of functions are quite often created as a separate service, which results in uncontrolled growth of the ecosystem. It can be challenging for developers, QA, DevOps staff, and infrastructure teams to keep track of and maintain all of those services in the long term. 

Depending on the project, a better approach to the problem of decomposing a system into microservices could be to think in terms of domains and bounded contexts as defined by domain-driven design. Then, the number of services can be minimized by choosing to implement each domain in just one or a few microservices. While the resulting services might not be quite so small, they are still responsible for a single area of the business domain, so most changes required by the business can be contained within a single service. This approach maximizes the benefits of microservices while minimizing the drawbacks. 

8. Not including monolith changes in the migration plan

An important benefit of using a microservices architecture is that you can gradually migrate your system from a monolith to microservices-based application instead of building a new system from scratch while wasting a lot of resources simultaneously maintaining a legacy system. In that case, it is crucial to carefully plan all aspects of coexistence between the microservices and monolith for an extended period of time. Generally, the monolith will require substantial changes upfront to play well with microservices, but this effort will pay off later on when you are able to manage the monolith in a similar way as a microservice. The important aspects of monolith changes include designing or extending an existing API for interservice communication, assuring multiple monolith instances can be run together, and creating a containerization configuration for your monolith so that it can be run next to the other services. 

9. Rushing the migration without appropriate expertise

A microservices architecture adds another level of complexity onto other complexities that are present in any software project. For a microservices project to succeed and actually benefit from the microservice architecture, it has to be designed and built according to general best practices adjusted to the particular use case. Resilience, eventual consistency, saga pattern, asynchronous messaging – all of these concepts need to be carefully planned, introduced to the system, and maintained properly for the system to work.

Therefore, it is extremely important that the developers engaged in the migration have previous experience in microservices design or at least have plenty of time to investigate and research the topic. Having a team of microservices veterans that have a proven track record of navigating migration projects through uncertainties is the best approach to make sure that your project is a success. Here you can read some success stories of how others utilized external microservice teams. If you do not have engineers at your company with the requisite experience, we would be happy to help.

Although we covered as much ground as possible in this short article, there is plenty more to be said on the topic of microservices migration. If you found this article useful or interesting, take a look at our ebook with more details on the migration process as well as real-world case studies on implementing microservices in companies of all sizes.

Latest Posts
now next later roadmap

Navigate Easily: A Step-by-Step Guide to the Now Next Later Roadmap

Let’s be honest – strategic planning is essential for successful product management. The Now-Next-Later roadmap is a powerful tool that helps teams prioritize tasks, streamline efforts, and align stakeholders. This guide delves into the intricacies of this roadmap, providing a comprehensive overview of its benefits and implementation. But first, let’s get some basics down for […]

/

Scrum: How to Work Together

With the popularity of the scrum framework among software development teams, it’s growingly important to learn how a scrum team works to meet its goals. Scrum Process Overview Scrum is an agile project management framework widely used in IT but can be applied to other fields as well. The framework facilitates the management of complex […]

/
event storming

Event Storming: How to Boost Your Software Development Process with a Simple Technique?

Event storming is a dynamic workshop technique that supports domain-driven design in software development. It can boost the team’s efficiency and reduce error risk, minimizing the back-and-forth in the development lifecycle. If you haven’t been living under a rock, you’re probably familiar with the concept of brainstorming. It’s a widely used term for the process […]

/
rails vs sinatra

Rails vs Sinatra

In the rapidly evolving world of software development, web frameworks have become essential tools for building robust and scalable web applications. These frameworks provide a structured environment that streamlines the development process, offering pre-written code, libraries, and guidelines that help developers avoid repetitive coding tasks, thus significantly enhancing productivity and ensuring best practices. Within the […]

/
android webstockets

Introduction to Android WebSocket

WebSockets have become a pivotal technology in enabling real-time communication for Android apps, offering a dynamic way to send and receive messages instantaneously. This technology facilitates a persistent connection between the client (Android app) and the server, bypassing the traditional HTTP request-response model to allow continuous data flow through a single TCP connection. The WebSocket […]

/
smart contracts audit

Introduction to Smart Contract Audits

In the blockchain world, smart contracts are key to decentralized applications (dApps), automating transactions and enforcing agreements without intermediaries. These contracts handle significant digital assets and perform crucial operations, making their security paramount. Smart contract audits are thus essential, scrutinizing the contract’s code for vulnerabilities to prevent potential security breaches. These audits are crucial for […]

/
Related posts

9 Most Common Mistakes when Migrating from Monolith to Microservices

With the microservices architecture gaining a lot of traction in the software world, more and more companies are migrating from their existing monolith to microservices architecture. Typically, this is a wise move, but great care needs to be taken in order to complete this process successfully. Below, we have gathered the nine most common issues […]

/

Should we follow new technology trends and rewrite our existing systems?

The lifetimes of custom business systems seem to be getting shorter. One reason for this is the rapidly evolving technology world, which gives frequent new opportunities for business development. The decision to create a new system is often driven by limitations of an existing system that negatively affect or threaten a business’s growth. This is […]

/

How outsourcing microservices helps to scale tech products

Let’s run through an example scenario. Say a company has their first MVP on the market. It is well-received by the market and brings clients and investors on-board. The product is well-designed and it works, but it has room for improvement. The product has great potential, but V2 needs to be more polished and further […]

/
Puzzle 3D

Who should consider migrating to microservices?

The microservice-based approach produces a type of architecture that has a more spread out and unit-focused philosophy than a traditional monolith. Favoring flexibility and scalability, microservices may be the perfect solution for companies that want to quickly bring their systems to the next level. Granted one size does not fit all, so it’s good to […]

/

Success stories of offshoring microservices development to CEE

Why CEE? Central Eastern Europe (CEE) is an extremely fast-developing part of the world. Many companies have already seen the potential of the region and incorporated it into their development strategies. Both global corporations and start-up companies are bringing their assets to the region; over 2,000 Shared Service Centers (SSCs) are open in the region.  […]

/
Talk with experts

We look forward to hearing from you to start expanding your business together.

Email icon [email protected] Phone icon +1 (888) 413 3806