Microservices vs. monolithic architecture
When monoliths grow too big it may be time to transition to microservices
A monolithic application is built as a single unified unit while a microservices architecture is a collection of smaller, independently deployable services. Which one is right for you? It depends on a number of factors.
In 2009 Netflix faced growing pains. Its infrastructure couldn’t keep up with the demand for its rapidly growing video streaming services. The company decided to migrate its IT infrastructure from its private data centers to a public cloud and replace its monolithic architecture with a microservices architecture. The only problem was, the term “microservices” didn’t exist and the structure wasn’t well-known.
Netflix became one of the first high-profile companies to successfully migrate from a monolith to a cloud-based microservices architecture. It won the 2015 JAX Special Jury award in part due to this new infrastructure that internalized DevOps. Today, Netflix has more than a thousand microservices that manage and support separate parts of the platform, while its engineers deploy code frequently, sometimes thousands of times each day.
Netflix was an early pioneer in what has become increasingly common today: transitioning from a monolith architecture to a microservices architecture.
What is a monolithic architecture?
A monolithic architecture is a traditional model of a software program, which is built as a unified unit that is self-contained and independent from other applications. The word “monolith” is often attributed to something large and glacial, which isn’t far from the truth of a monolith architecture for software design. A monolithic architecture is a singular, large computing network with one code base that couples all of the business concerns together. To make a change to this sort of application requires updating the entire stack by accessing the code base and building and deploying an updated version of the service-side interface. This makes updates restrictive and time-consuming.
Monoliths can be convenient early on in a project's life for ease of code management, cognitive overhead, and deployment. This allows everything in the monolith to be released at once.
How to build microservices
Manage your components with Compass
Advantages of a monolithic architecture
Organizations can benefit from either a monolithic or microservices architecture, depending on a number of different factors. When developing using a monolithic architecture, the primary advantage is fast development speed due to the simplicity of having an application based on one code base.
The advantages of a monolithic architecture include:
Easy deployment – One executable file or directory makes deployment easier.
Development – When an application is built with one code base, it is easier to develop.
Performance – In a centralized code base and repository, one API can often perform the same function that numerous APIs perform with microservices.
Simplified testing – Since a monolithic application is a single, centralized unit, end-to-end testing can be performed faster than with a distributed application.
Easy debugging – With all code located in one place, it’s easier to follow a request and find an issue.
Disadvantages of a monolithic architecture
As with the case of Netflix, monolithic applications can be quite effective until they grow too large and scaling becomes a challenge. Making a small change in a single function requires compiling and testing the entire platform, which goes against the agile approach today’s developers favor.
The disadvantages of a monolith include:
Slower development speed – A large, monolithic application makes development more complex and slower.
Scalability – You can’t scale individual components.
Reliability – If there’s an error in any module, it could affect the entire application’s availability.
Barrier to technology adoption – Any changes in the framework or language affects the entire application, making changes often expensive and time-consuming.
Lack of flexibility – A monolith is constrained by the technologies already used in the monolith.
Deployment – A small change to a monolithic application requires the redeployment of the entire monolith.
What are microservices?
A microservices architecture, also simply known as microservices, is an architectural method that relies on a series of independently deployable services. These services have their own business logic and database with a specific goal. Updating, testing, deployment, and scaling occur within each service. Microservices decouple major business, domain-specific concerns into separate, independent code bases. Microservices don’t reduce complexity, but they make any complexity visible and more manageable by separating tasks into smaller processes that function independently of each other and contribute to the overall whole.
Adopting microservices often goes hand in hand with DevOps, since they are the basis for continuous delivery practices that allow teams to adapt quickly to user requirements.
Atlassian’s journey to microservices
Atlassian followed the path to microservices in 2018 after we faced growing and scaling challenges with Jira and Confluence. We found that our single-tenant, monolithic architectures running on premise would not be able to scale to future needs.
We decided to re-architect Jira and Confluence and move them from a stateful, single-tenant monolithic system to multi-tenant, stateless cloud applications hosted by Amazon Web Services (AWS). Then we would decompose them over time into microservices. The project was named Vertigo, after a senior engineer said, “I really like the idea, but it’s giving me vertigo.” It was our largest infrastructure project to date, taking two years to complete the transition to AWS, migrating more than 100,000 customers in just over 10 months with no service interruptions. We also committed to decomposing the services to microservices.
Advantages of microservices
Microservices are by no means a silver bullet, but they solve a number of problems for growing software and companies. Since a microservices architecture consists of units that run independently, each service can be developed, updated, deployed, and scaled without affecting the other services. Software updates can be performed more frequently, with improved reliability, uptime, and performance. We went from pushing updates once a week, to two to three times a day.
As Atlassian grows, microservices enable us to scale teams and geographic locations more reliably by splitting along lines of service ownership. Before we started Vertigo, Atlassian had five different development centers around the world. These distributed teams were constrained by a centralized monolith and we needed to support them in an autonomous fashion. Microservices allow us to do so.
The benefits of Vertigo include increased deployment speed, disaster recovery, reduced cost, and higher performance. This allows us to get to our target faster while delivering more incremental value to customers along the way.
Plus, more generally, microservices make it easier for teams to update code and accelerate release cycles with continuous integration and continuous delivery (CI/CD). Teams can experiment with code and roll back if something goes wrong.
In short, the advantages of microservices are:
Agility – Promote agile ways of working with small teams that deploy frequently.
Flexible scaling – If a microservice reaches its load capacity, new instances of that service can rapidly be deployed to the accompanying cluster to help relieve pressure. We are now multi-tenanant and stateless with customers spread across multiple instances. Now we can support much larger instance sizes.
Continuous deployment – We now have frequent and faster release cycles. Before we would push out updates once a week and now we can do so about two to three times a day.
Highly maintainable and testable – Teams can experiment with new features and roll back if something doesn’t work. This makes it easier to update code and accelerates time-to-market for new features. Plus, it is easy to isolate and fix faults and bugs in individual services.
Independently deployable – Since microservices are individual units they allow for fast and easy independent deployment of individual features.
Technology flexibility – Microservice architectures allow teams the freedom to select the tools they desire.
High reliability – You can deploy changes for a specific service, without the threat of bringing down the entire application.
Happier teams – The Atlassian teams who work with microservices are a lot happier, since they are more autonomous and can build and deploy themselves without waiting weeks for a pull request to be approved.
Disadvantages of microservices
When we moved from a small number of monolithic codebases to many more distributed systems and services powering our products, unintended complexity arose. We initially struggled to add new capabilities with the same velocity and confidence as we had done in the past. Microservices can add increased complexity that leads to development sprawl, or rapid and unmanaged growth. It can be challenging to determine how different components relate to each other, who owns a particular software component, or how to avoid interfering with dependent components.
With Vertigo, we built a common functionality that would power our existing products and future products we acquire and build. If you are a single product company, microservices may not be necessary.
The disadvantages of microservices can include:
Development sprawl – Microservices add more complexity compared to a monolith architecture, since there are more services in more places created by multiple teams. If development sprawl isn’t properly managed, it results in slower development speed and poor operational performance.
Exponential infrastructure costs – Each new microservice can have its own cost for test suite, deployment playbooks, hosting infrastructure, monitoring tools, and more.
Added organizational overhead – Teams need to add another level of communication and collaboration to coordinate updates and interfaces.
Debugging challenges – Each microservice has its own set of logs, which makes debugging more complicated. Plus, a single business process can run across multiple machines, further complicating debugging.
Lack of standardization – Without a common platform, there can be a proliferation of languages, logging standards, and monitoring.
Lack of clear ownership – As more services are introduced, so are the number of teams running those services. Over time it becomes difficult to know the available services a team can leverage and who to contact for support.
Atlassian’s tips to migrate from a monolith to microservices architecture
Many projects initially start out as a monolith and then evolve into a microservice architecture. As new features are added to a monolith, it may start to become cumbersome to have many developers working on a singular codebase. Code conflicts become more frequent and the risk of updates to one feature introducing bugs in an unrelated feature increases. When these undesirable patterns arise, it may be time to consider a migration to microservices.
The following are some of the best practices we learned from our migration:
Map out a migration strategy
We dedicated a significant amount of time determining the sequence of how we wanted to migrate customers. We knew many of our customers would have different profiles and different usage dynamics once we migrated them, so we planned accordingly beforehand.
The right tools are essential when undergoing a microserivces migration. We didn’t migrate customers right away, but rather first invested and created tools for the migration, knowing it was a marathon instead of a sprint. The most important tool we built was Microscope, our own internal service catalog to track all the microservices. Every developer at Atlassian can use Microscope to see all the information of any microservice in the company.
We also built tooling in Microscope called ServiceQuest that automtically detects checks on code before production, which includes checks for quality, service design, privacy, security, and reliability.
Plus, a tool was built around our tech stacks. We have a service internally that allows us to spin up a new service on a particular stack and it precedes things like logging, monitoring, and cacheing. Finally, we automated as much as we could, including the migration process itself. We created our own dashboard to view all migrations effectively in real time.
A company transformation requires a senior executive sponsor who is accountable for results and is willing to enforce the necessary tradeoffs, said Sri Viswanath, CTO of Atlassian. This person should enable the organization to invest in new tools, systems, and processes to make improvements permanent.
With a large infrastructure migration with a lot of people involved, the business wants to know about the return on investment, said Mike Tria, Head of Platform at Atlassian. It’s very important to keep up communications with the executive team, stakeholders, customers, partners, and the rest of the R&D teams. Ensure they know what you’re doing, including expected benefits. Plus, be sure you celebrate successes.
Embrace a culture shift
"Culture matters a lot in these kinds of massive projects," said Viswanath. "You want to make sure when there's an issue that it's percolated up every single time." When you do a migration, it's not just a technical migration, but a people and organizational change. Atlassian in 2015 was a “write the code and throw it over the wall” to the operations team who ran and deployed it. By the end of 2017, we embraced a DevOps culture of “you build it, you run it”, with every developer at Atlassian running their own services.
“I spent more time making sure that our SRE team was successful in this project than almost any other work that I did during the project because the cultural shift was the biggest long-term difference for Atlassian as a result of Vertigo,” Tria said.
Balance speed and trust
Vertigo could’ve been done much faster. After the first four months, we completed 80 percent of the migrations. We could’ve migrated the last portion of users even though we couldn’t guarantee that they would have the reliability and performance that we wanted. We aligned with one of Atlassian's core values: Don’t #@!% the customer.
We established a system of checks and balances with our engineers in order to maintain high reliability and we met the high standards we set out to achieve. Because if you build it right the first time, you will save time and headaches in the long run.
When we got down to the last 500 customers, which were the toughest customers to migrate, we used the Jira Software and Trello integration to assign each customer to an Atlassian engineer.
In January 2016, we had about 15 total microservices. Now we have more than 1300. We moved 100K customers to the cloud, built a new platform along the way, transformed our culture, and ended up with new tools. We have happier, autonomous teams and a better DevOps culture.
Microservices may not be for everyone. A legacy monolith may work perfectly well, and breaking it down may not be worth the trouble. But as organizations grow and the demands on their applications increase, microservices architecture can be worthwhile.
Since the trend for many organizations is microservices with distributed architectures, Atlassian developed Compass to help companies manage the complexity of distributed architectures as they scale. It’s an extensible developer experience platform that brings disconnected information about all of the engineering output and team collaboration together in a central, searchable location.
Share this article
Bookmark these resources to learn about types of DevOps teams, or for ongoing updates about DevOps at Atlassian.