Back in 2009, Netflix was growing quickly and running into problems with scaling, so its developers decided to try moving the codebase onto separate servers on the cloud. That’s how the company pioneered the use of microservice architecture, when “microservices” wasn’t even a term yet.
At the time, it seemed like a crazy thing to do, but developers soon saw the benefits of microservice architecture. Work was more cleanly separated and when combined with cloud hosting, it could save costs by scaling different services at different rates.
Soon, microservices were so popular that companies started thinking it was the only correct way to implement software architecture.
What Are Microservices?
“There was a big push, back when microservices first started, to re-implement everything in microservices,” said Mark Little, vice president of engineering at Red Hat. “That kind of painted monoliths as bad — and that’s completely wrong.”
New applications started being built as microservices from the start and even older monolith applications, which are built as single units of software, that worked well got unnecessarily reworked into microservices. Since then, there has been a backlash against this overreliance on microservices, but it can still be difficult to know how to strike the right balance.
Knowing when and how to implement microservices correctly comes down to the basic question of what microservices are and how they’re different from monoliths.
What Is a Microservice Architecture?
Microservice architecture is a way of designing code so that different parts of the application can function independently and each part can be hosted on a different server. The concept is usually contrasted with monolithic architecture, which has interdependent codebases that are hosted together.
Christian Avery, founder of security gig startup Getaguard, said that fundamentally, microservices have loosely coupled rather than tightly coupled components.
He gave the example of an e-commerce website, which could be implemented as a monolith. All the code in the codebase would belong to one large application file and everything would be deployed together every time.
“Rather than having a roomful of developers who are all going to edit the same codebase, we’re going to put two developers on one of these services, two developers on another.”
But if the same e-commerce website is built as microservices, it could be split into different applications. One service could handle user authentication to the site, including code that supports important functions like user account creation, password resets, and login and logouts. The bulk of the website might exist as another application and other services, like payment, could be yet another application. Each microservice in the project would communicate to the others through APIs, limiting the interactions and allowing different sections to be more independent.
Avery said the microservice setup allows different teams to work on separate parts of the website without any developer stepping on another’s toes.
“Rather than having a roomful of developers who are all going to edit the same codebase, we’re going to put two developers on one of these services, two developers on another,” he said. “They’re going to have end-to-end responsibility for everything, from delivering the user requirements to the unit testing.”
Because each service can be deployed to different servers, companies can adjust the characteristics of each server individually — if certain parts of a website see more traffic than others, that server can be singled out to be made more highly available and robust.
Microservices Give Companies Flexibility With Scaling
That flexibility is one of the advantages of microservices, said Sergii Zhuravel, software engineer at Temy. Using Gmail as an example, he explained that it can save companies money to put low-priority services on servers that are not as highly available as others.
Services that provide antivirus protection, in the case of Gmail, are nice to have, but not vital to sending and receiving emails — even if that service goes down, users can still use Gmail and may not even notice the difference. It can make a big difference in effort and cost to ensure a service is up all the time, rather than 99 percent of the time.
On the other hand, companies can also save money by selectively scaling up parts of the application that are under more strain than others. When microservice architecture is combined with cloud hosting, companies can also take advantage of autoscaling, where overloaded servers will automatically scale up, preventing potential problems. In that case, microservices can still be cost-effective because unaffected services aren’t unnecessarily scaled up, which costs more money.
They Fit Well With an Agile Workflow
Microservices fit better with the agile style of development than monolith architectures do, Little said. Monoliths are instead better suited for waterfall, where developers work on large portions of code at a time and iterate slowly.
“It’s great if you’re only ever releasing something once every 12 months,” Little said. “But if you want to release something to customers every hour or five or six times a day, it just doesn’t work.”
It’s easy to organize distinct teams around different parts of an application using microservices because each service’s code is already distinct from the rest. That allows teams to iterate more effectively, especially for larger projects.
Microservices Are Better Suited for Frequent Updates
Microservices make updating applications easier. Blair Lyon, vice president of cloud experience at Linode, an independent cloud provider company, said that when monoliths have large codebases, even standard deployment procedures can become bottlenecks.
“Even re-compiling the codebase and publishing it, depending how big your monolithic application is, can be hugely time consuming — and require a lot of time and bandwidth and processor ability,” Lyon said. “Think of eBay, for instance: If all of their different features was one application — from support to billing to payments to the ability to run bidding — oh my gosh, just imagine trying to recompile the entire codebase just because you changed one small thing. That would be painful.”
When the business asks the development team to add “just one thing” again, it’s easier if the project is more fragmented, rather than needing to redeploy the entire codebase for that change.
Developers Want to Feel Ownership Over Their Code
Microservices can be helpful for individual developers as well. When applications are split into microservices, it’s easier for people to wrap their minds around each service, rather than an entire monolith application. Individual developers or teams can also be put in charge of certain services.
Avery stressed the importance of having responsibility over code on developers’ motivations — it’s easier for developers to have a sense of accountability and pride over the code that they are in charge of.
“It’s very easy, when you’ve got a big architecture, for it to be unclear who isn’t contributing as much as they should be,” Avery said. “Obviously, you have code reviews, you have check-ins, but you’re masked by the size of the team.”
When developers are responsible for an entire service, it can also result in less errors and bugs because the same people writing the code are ensuring that it’s working correctly.
But Microservices Add a Lot of Complexity
Not all aspects of microservices are desirable. Avery said that when companies make the move to microservices, it adds a lot of complexity to the development process. That’s because microservices necessarily require more servers, which have to be managed separately with different configurations for each of them.
“You can very easily end up with multi-cloud deployments,” he said. “You’ve got deployments that are in different availability zones, different [storage volumes]. So you’ve got all this extra complexity in terms of getting things into production and getting them deployed.”
Microservices also require a robust DevOps team to help with cloud configurations and deployment pipelines. It can be challenging to manage interactions without breaking anything each time code is deployed.
Microservices Can Make Debugging More Difficult
Microservices can also make troubleshooting errors in production harder because they’re more difficult than monoliths to debug. Monolith codebases run all together, and when problems occur, the error logs can be found in the same location. But with microservices, tracking down all the different places logs are kept can prove difficult. Moreover, sometimes logs are hard to access.
“First of all, realizing that a microservice has gone down can be hard because networks are slow and machines can sometimes drop responses,” Little said. “And then you have to try and do a distributed debugging session, which is really hard, especially if the machine that your microservice ran on when it failed isn’t in your domain and is not something you can get access to.”
Microservices Mean a More Brittle Application
One significant disadvantage of microservices is that if a single service goes down, the entire application could be rendered unusable for users.
“If a microservice fails that is critical to the overall functioning of my application — even if 99 percent of the other microservices are running fine — my application can’t make forward progress,” Little said. “Having too many microservices in a single application may make your application more brittle.”
He said the right approach is to aim for a “Goldilocks effect” — not creating a strict monolith, but not splitting a project into too many microservices either. Companies can have redundancies for the remaining critical services to protect against one failure causing a larger outage.
Your Greenfield Application Should Probably Be a Monolith
When Avery first started working on the codebase for Getaguard, he was tempted to start coding the greenfield application using a microservice architecture, in anticipation of eventually scaling up. But then he remembered the advice he was given to start simple and optimize only once the need arises.
“Don’t count on having a popular service in advance,” he said. “You want to build as fast as possible and the fastest way to build was to build a monolith.”
After finishing the initial product as a monolith, Avery split the application into microservices based on where it made sense to create modules. He said that approach was successful in helping him avoid over-engineering his product and getting it off the ground quickly.
“You want to build as fast as possible and the fastest way to build was to build a monolith.”
Developers should avoid “upgrading” monolith applications to microservices without a real need to do so. If the monolith needs updates all the time and updating is cumbersome, that may be the right sign to make the switch.
“If you’ve got monoliths that are already out there and running fine, and your business is happy with them, don’t change them,” Little said. “Don’t just don’t start re-implementing something. If it works, you have no real reason to do it.”
Instead of Monoliths or Microservices, Think Modular
When building new applications, developers shouldn’t start with choosing between monoliths and microservices. Instead, Little emphasized the importance of looking at the project holistically and figuring out where the natural boundaries between modules are.
“At the early stage of architecting an application, you shouldn’t be thinking about services or microservices — you should be thinking in terms of modularity,” Little said. “Modularity is a way of segmenting software code such that you have a well-contained interface.”
Grouping code into the right modules makes it cleaner and cleaner code is less interdependent, and easier to maintain and update. After developers determine an application’s modularity, splitting up microservices becomes much more straightforward.
How Often Does the Application Need Updating?
If a monolith application needs constant updating, it could be a sign that the project would be better split into microservices. Separating services can save time because only small portions of the codebase would need to be redeployed during each update.
Randy Potter, lead architect at Capgemini, a technology consulting company, recommended that developers have candid conversations with product managers and customers about how often applications should expect to be deployed. It’s important to have honest discussions because deployment frequency can determine which type of architectural style makes the most sense.
“If it’s less than once a month, consider a microservice,” Potter said. “If it’s less than once a week, you should be doing a microservice.”
Make Sure Your Team Is on Board
Even if all other factors are aligned, not having the right DevOps infrastructure in place can throw off attempts to create greenfield microservice applications. If companies have to build out most of the infrastructure from scratch, Potter advises against using microservices.
“If I’m not already doing DevOps and I’m not doing cloud native development, then that’s going to add a lot, going from that point to doing microservices — it’s going to be costly,” Potter said. “That’s going to be costly from a culture shift perspective, as well as from a monetary perspective.”
Having the right people in place can count for a lot and he recommended development teams check that all members are on board before jumping into a microservices project. Because microservices are an architectural style, everyone may not initially agree on exactly what it means to implement an application using microservices.
“Make sure you define your microservice structure so people understand how fine-grained it should be and what it is supposed to address,” Potter said.