Getting Microservices Right: Clearing Up Common Mistakes and Misunderstandings

Berk Gökden
Berk Gökden’s adventures
5 min readJun 7, 2023

--

As an advocate for microservices, I feel it is essential to address some common mistakes that have led to recent pushback in the market. Microservices architecture has gained significant popularity in recent years due to its potential for scalability, agility, and fault isolation. However, certain misconceptions and missteps can hinder the successful implementation and adoption of microservices. In this article, we will explore these common mistakes and provide insights to help clarify the principles and best practices of microservices. I will try to be less technical and keep the discussion at the architectural level.

I plan to discuss several key points in microservices architecture development, although I won’t cover everything in this article. There are many aspects to consider in this field, and I look forward to delving into more detail in future posts.

Leveraging my extensive experience in implementing, troubleshooting, and consulting on microservices for numerous companies, I’ve noticed a recurring issue. Often, organizations tend to choose tools or technologies based on their popularity, rather than their applicability to the situation at hand.

As a seasoned expert, I’ve witnessed how decisions made in a hurry or without sufficient understanding can lead to complications later. For instance, a company may decide to use gRPC due to its quickness and efficiency. But if their team is more familiar with REST APIs, and their system is built around it, the gRPC implementation could become a bottleneck, slowing down the whole process.

Therefore, it’s crucial to assess technologies based on the company’s unique needs, current tech stack, and team’s know-how. If new technologies are under consideration, getting expert advice or training can prove highly advantageous. By adopting such mindful planning, organizations can sidestep common hurdles and truly harness the potential of microservices.

In the market, AWS Serverless, particularly AWS Lambda, is often used as an example when discussing microservices. However, it’s important to note that any problems or challenges faced with AWS Serverless should not be attributed to microservices as a whole. These issues are more likely related to specific implementation choices or limitations within the AWS Serverless platform itself. It should only be used for stateless, occasionally called, small services.

AWS Serverless is not always a good solution.

Infrastructure:

In my extensive work of implementing, troubleshooting, and advising on microservices for many companies, I’ve found that having a robust and well-managed infrastructure is a cornerstone of success. It’s like having a good foundation for a house — if it’s strong, everything you build on it will be more stable and effective. The right infrastructure makes it easier to add new services, manage loads effectively, spot problems quickly, measure performance, and alert the right people when something needs attention.

By setting up the right infrastructure from the start, companies can avoid many common problems, making their microservices more efficient, reliable, and easier to manage. This is a key point I always emphasize in my consulting work, because I’ve seen firsthand how much of a difference it can make.

This infrastructure should be able to handle scaling, logging, metrics, and alerting tasks. This way, each service doesn’t need to worry about these aspects and can focus on its own specific job.

DevOps:

In my experience guiding companies with microservices, the DevOps mindset is crucial. It allows developers to independently set up a service and a CI/CD pipeline within their sandbox in a few hours, following a straightforward guide. This self-sufficiency speeds up development, fosters system understanding, and improves teamwork. The result is a more robust and efficient microservice architecture. Combining this DevOps approach with solid infrastructure helps companies fully benefit from microservices.

On Independent Code Repo Per Service:

I advocate for maintaining mini independent code repositories instead of monorepos for each microservice. Services should avoid code dependencies on each other. This method keeps the code simple and allows for independent updates. It enables swift CI/CD and independent deployment. This approach helps to avoid code conflicts, which can slow down development in the future.

It’s unfortunate to see senior developers advocating for monorepos. They often justify this by pointing to large companies that use a single monorepo. However, this approach can result in slow and complicated development environments. While Google is known for using a monorepo, they have a unique file system and a dedicated DevOps team supporting it, which allows for separate folder updates, diverging from the true essence of a monorepo.

Simply because a method was used before DevOps came into the picture or because a successful company like Google uses it doesn’t make it the right choice for every situation. This misconception is a common problem in large companies and often leads to inefficiencies and complexities. Independent repositories for each service promote simpler code, faster CI/CD, and independent deployment, which are crucial for efficient microservices architecture.

Responsibilities:

Each service should have a dedicated owner. Leaving services unmaintained and ownerless is a frequent error. This also connects to another common error that including shared libraries with other services. Services should not carry extra code or libraries for logging or metrics, as these tasks should be handled by the infrastructure. Incorporating these operations into the service itself is a leftover practice from older times, contradicting modern DevOps principles. This makes updating and maintaining microservices an issue and also a liability in the future. It creates a wall to migrations.

Size:

The question of microservice size often comes up and I find it quite misguided. It seems like a relic from the Waterfall era. Although one could argue that a microservice should be small enough for a single developer to rewrite, this perspective isn’t entirely accurate. Service development isn’t static; the functionality of a service isn’t always defined from the start. Typically, you might begin by adding a new functionality to an existing service. As this functionality matures and expands, it may graduate and become a standalone service.

Final thoughts:

I was motivated to write this article because many companies struggle with effective microservice implementation. This often results in slower development, increased costs, never-ending migrations, and even developers leaving the company. It’s disheartening to see senior developers and managers sometimes make poor decisions. For example, developers might attempt to implement a microservice without the right infrastructure, leading to issues down the line.

With current tools like Kubernetes as a service, load balancers, reverse proxies, managed code repositories, and infrastructure as a service, setting up a microservices infrastructure is achievable without excessive cost. An experienced engineer can easily navigate these technologies. If you’re unsure or need guidance, just reach out to an expert in the field.

I hope this article has provided some valuable insights for you. Should you have any comments or queries, don’t hesitate to leave a comment or connect with me directly on LinkedIn. I’m always eager to engage in meaningful discussions on this topic. Additionally, if you’re seeking professional assistance, I offer services to help restructure your architecture and provide recommendations on strategic decisions. I look forward to hearing from you.

My Linkedin: https://www.linkedin.com/in/berkgokden/

--

--