Hey, I’m Colin! I help PMs and business leaders improve their technical skills through real-world case studies. For more, check out my Live cohort course and subscribe on Substack.
As your product grows, understanding the technical architecture supporting it becomes increasingly critical to your ability to ship features quickly and reliably.
Let's explore monoliths, microservices, and why they matter.
What is a monolith?
A monolith is the traditional software architecture for web applications. It has a single codebase containing all services and features. This includes user authentication, business logic, database updates, email notifications, and more. It's common that parts of the application interact across services whenever they need, without clearly defined inputs or outputs.
For example, Shopify’s monolith had shipping rate calculations that directly interacted with their checkout code. These two services could talk directly inside the same application without communicating over the internet. While this seems efficient initially, it made it increasingly difficult to modify either shipping or checkout features without risking bugs in both systems.
Uber also grew using two monolithic applications up until 2013. Their monoliths had time consuming deployments, costly bugs, and they found it challenging for teams to work independently.
Monolithic applications get deployed as a single unit. This means you only have one deployment process and that each deployment touches every part of the application.
Scheduled releases are commonly used with monoliths to de-risk releases and ensure that new features have been thoroughly tested. Once deployed, the entire application runs on each server. To scale a monolith, you can either purchase better hardware for the server or use multiple servers, which each run the entire application.
Monoliths are easier to use at the beginning of a project, as all code is contained within a single codebase. It’s very easy to access data and the simple architecture reduces complexity with deployment and scaling.
Monoliths usually cause issues at scale, where many developers are working on the same codebase at the same time.
In Shopify’s case, the dependency between shipping rates and tax code meant that making changes to tax code could inadvertently change how shipping rates were calculated. Not only is this frustrating for developers to resolve, but solutions felt like playing whack-a-mole. Teams lost confidence in their ability to ship new features, each change requires extensive testing, and customer requests start to pile up.
To solve for these dependencies, many companies move to microservices.
What is a microservice?
A microservice breaks down the web application into a series of internal services. Each service is hosted independently and can be updated without making any changes to other services.
Each microservice is hosted on its own server. Because they don’t share any code or require access to the same data, each service can be scaled independently.
These services often communicate with each other through APIs. These are well defined contracts that state what types of requests the service can receive and what operations it can perform. When completing a customer workflow, API calls flow between services.
For example, this workflow shows what the backend might look like when a customer makes a purchase on an ecommerce site.
Microservices are often used when an application or team scales. They excel at scaling specific components of the application so the overall product performs well under load. Microservices are also easier to orient large teams around, as each team can take responsibility for one or more services.
Microservices can also be extremely complex to manage. As the number of services grows, it can be challenging to determine exactly how a user workflow actually works. New team dependencies are created, and missed context or requirements can lead to late-stage blowups as you try to get on another team’s roadmap last minute.
Uber, for example, ended up with a large, complex set of interdependent microservices after migrating from a monolith.
What a PM should know
Working with either a microservice or monolithic architecture brings its own challenges.
Monoliths
When working on a monolith, shipping features will be extremely fast at the beginning and begin to slow down as you scale. Developers may begin to feel less comfortable making changes, and you likely have a few critical developers who understand how the whole system works.
As a PM, you should be aware of the cost of technical debt and think about how you can incrementally improve it. How comfortable are engineers with making changes? How much time is being spent on testing? What is the risk of regressions or bugs? Consider moving towards automated testing using CI/CD patterns to reduce the risk of deployments.
If you have a new service, like a recommendation engine, consider building it as an external service. Make sure that devops or your infrastructure team is in the loop early if you plan on making an investment in changing your architecture.
If you’re a PM on a team who is going through this transition, remember that engineers will be much more focused on application functionality than user workflows. Make sure you represent the user’s perspective on what features and behaviour is critical.
Consider:
Regularly assessing engineer comfort with making changes
Assessing time spent on manual testing vs feature development
Incremental improvements through automated testing
Keeping user workflows central during migrations
Microservices
If you’re a PM working on a microservice, you might feel disconnected from other parts of the application and the user’s journey. Make sure you understand what other services depend on you, and what services you depend on. Consider mapping out the user’s journey through your product’s microservices to better understand dependencies and interactions.
When roadmapping, share your plans early and often. It’s likely that another team will be involved in your feature, either to coordinate changes or implement something you need.
Your engineering team likely won’t be familiar with the entire application and will naturally answer questions from the perspective of services they know. Make sure you ask if any other teams or services need changes when planning new features.
PMs working in a microservices environment should:
Map and document service dependencies
Share roadmaps early to coordinate cross-team dependencies
Build relationships with dependent teams
Maintain focus on end-to-end user experience
Spotting Architecture Problems Early
Whether you're working with a monolith or microservices, certain patterns often emerge when your architecture needs attention. You might notice your teams spending more time waiting for other teams than actually building features. Engineers who were once confident making changes start expressing hesitation, asking for extensive reviews, or wanting to coordinate across multiple teams for even simple updates.
Watch especially for an increase in production incidents after deployments - this often indicates your architecture isn't effectively isolating changes. In microservice architectures, you might see rising tension between teams about service boundaries and responsibilities. With monoliths, you might find that only a handful of engineers feel comfortable explaining how core features actually work.
These signs don't necessarily mean you need to change your architecture immediately, but they should prompt deeper conversations with your engineering leads about technical strategy. Often, small incremental improvements can address these issues before they become critical problems.
Putting it all together
Software architecture might seem irrelevant to product management, but it fundamentally shapes your ability to deliver value to customers. Understanding your architecture helps you:
Ship features successfully
See around corners for potential risks
Have more productive technical discussions
Make better strategic decisions about technical investments
The best PMs don't need to be technical experts, but they do need to understand how their products are built and the implications for their team's ability to execute.
References:
Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity
Introducing Domain-Oriented Microservice Architecture | Uber Blog
If you liked this post, check out: