Software development, while still a relatively new profession, has gone through a couple of cycles already. First, we did everything in monoliths, then we started to break those monoliths down and focus on splitting the front end user facing code from the backend business logic. Then we started moving things from a single monolithic application into smaller individual apps. Now that micro services have been in the wild for a while, we have started looking back at more monolithic architectures.
As engineers and architects, we like to try and identify the “best” practices, architectures, languages, etc. to develop and deliver a solution to our business stakeholders. But, this is not a good practice to be in! Each business need requires a unique approach tailored to the business’s specific needs. Trying to apply a micro service architecture to a business’ use case that, truthfully, doesn’t need it.
So, let’s take a look at a simple business requirement for a web application. Let’s say you were contacted by a startup BookMore LLC., they handle hotel bookings as well as allowing venues to promote events and sell tickets to entertainment in New York City. This is a very competitive industry and market, so they have a tight deadline of getting a production ready application developed and in front of investors. Currently they are only targeting the NYC market, but have plans to expand to Chicago, Los Angeles, and St. Louis within 24 months.
If we were to take this hypothetical company’s solution and decide to go with a micro-service architecture, it might look something like the below image.
Now, this might not look overly complex but let’s pause a moment and think about this. Let’s say BookMore doesn’t have a gigantic budget for development, having all of these services, databases, the front-end, and an API gateway to handle all of the communication can be a cost prohibitive proposal. Next, let’s think timeline. Spinning up all these different services and databases can definitely take a fair amount of development and architecture time. The team is going to have to identify what logic needs to live in which service, what execution area is going to own which service, and how are we going to handle data consistency. That’s right, one of the things that’s commonly forgotten about with micro-services is how the team needs to handle data and eventual consistency. What data needs to live where, how do we get that data propagated to other services, what happens if data propagation fails, we have common code; do we need to duplicate it or pull it into a common library? These are all valid concerns and can eat up your development time.
We’ve see what a micro-service approach could be like for this solution, we know we’re on a tight deadline, and BookMore doesn’t have a high budget for MVP development. What approach can we use then? Well, it might sound like heresy but a monolith (or a few micro-monolith’s) might actually be the better choice for this. I know that “monolith” has become a bit of a curse word in today’s software development industry, but they’re not all bad. For a smaller application like this, we don’t really need to care about the benefits that micro-services provide. This would be more considered premature optimization, and to quote Donald Knuth from The Art of Computer Programming
“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.”
For an application that’s not targeted at a huge amount of users, not expecting hundreds of thousands of visitors every hour, you don’t need to worry all that much about how your system will perform under load. For the initial MVP, you could do something similar to the below diagram:
See how much simpler that is? You have one database to worry about, one set of services to maintain and you can focus on running them say in a Docker container with multiple instances running on Kubernetes to handle any issues, and fail over to another pod if for some reason your services crash. Then, in MVP 2.0 or 3.0 you can look at decomposing the monolith into micro-monoliths (like below) and the afore mentioned micro-services as need arises if traffic is increasing and more development efforts come underway.
In conclusion, what I want you to take away from this post is; don’t discount the monolith! You do not need to go full micro-service and micro-frontend from the start. A solution doesn’t have to be fully optimized right from the start, you don’t have to worry about supporting hundreds of thousands of users until you have to worry about it!
About Cory Gideon
I have worked as a consultant for Sogeti for two years at a client using .Net and lots of legacy applications. During my tenure with Sogeti, I have done multiple lunch and learns ranging in topics from advanced Azure Application Insights to Micro-Frontend architectures. I’m very passionate about system architecture and designing for maintainability and scalability. Sharing knowledge and technical experience with other developers is one of my favorite things to do. And I have conducted many lunch and learns and am starting to get into speaking at conferences.
More on Cory Gideon.