I started my career writing macros in Microsoft Excel. So, while I didn’t know how to write software, I could record macros for the things that I needed to do and go back to figure out how to change and edit things. It’s through this lens that I would like to tell a story of monoliths and microservices: Sometimes it is necessary to simply do whatever it takes to get the job done.
In engineering as a community, we’ve developed a great ability to revise history. The industry as a whole has the tendency to write blog posts and books about the perfect outcome -- as if we knew what we were doing the whole time -- when the reality is, no one had a clue. We’ve seen this same phenomenon with microservices.
In the world of microservices, there are two main viewpoints. One is the idea that a company should build its entire platform in microservices because Netflix and Amazon did it and they’re successful. The other viewpoint is the idea that as a start-up that needs to move fast and iterate quickly, microservices get too complex.
So, maybe you start with a monolith, scale and figure out your business until one day you realize you need microservices. The next thing that happens is you break open the box and all these services come out of nowhere and you have a perfect microservices architecture and move forward with that, right? That seems to be the consensus if you read the literature, which makes it seem like everything was perfect all along and we figured it all out. Except, that’s not the way it goes.
A cautionary tale of starting with services
In 2011, several colleagues and I started a business called Copious, a social marketplace. Using Rails and some backend services, the product used a social graph -- an overlay of everything we knew about someone from Facebook, Tumblr, Twitter, etc. -- and would allow publishing stories to social channels.
We concluded early on that all of this external data from social platforms would make sense as a service. As a smart group of engineers with a certain set of context, we decided that since people are now doing microservices, it made sense to go down this path. But the reality was that we actually had three different sets of data inside that social data:
- The graph: who I know, who my Facebook friends are, who I follow on Twitter, etc.
- The management of OAuth token interactions so users could sign in to our site by using Facebook or Twitter connect.
- Token storage and interactions with those platforms
If you want to have scaling problems long before you ever have a business, slurp in everyone else’s social graph -- we had terabytes of data in Mongo on EC2 before it had SSDs -- everything about it was awful. Inside those terabytes of data was about 200K of authentication tokens, which were required to allow someone to access our site. The service was collapsing all the time and when it was broken, users couldn’t get into our site.
That was not a great system. We had managed to build a front-end monolith and behind it we had a monolithic service. We had two monoliths, which is about the only thing worse than having one monolith.
But it gets better! On the site users were able to like, sell, buy or view products. Those things were not external data so they were stored in the main monolith. Whenever users wanted to understand if someone cared about something, they had to merge datasets from the monolith and the monolithic service. Two massive datasets being merged in a Rails web server. This was a complete disaster.
I think everyone is leaving this party so I should too...
What did we do at this point? We merged everything back into the monolith, which is a sure sign that we should not have been doing services so early. If it’s bad to go from a monolith to services, it’s a lot worse to go from a bunch of services to a monolith and then back to the right services.
If you don’t have a clear understanding of your business, product or where you fit in the stack, breaking things out prematurely into a bunch of services without knowing how they are going to be used is not going to be a fun outcome.
In conclusion, right now is a great time to be thinking about architecture, but it’s also important to do it in a way that is incremental and allows you to test ideas and validate them rather than trying to turn on a dime and build totally differently. That’s going to fail and turn into a nine month project that finishes with you telling your VP of engineering that, while you learned a lot, in the end the team decided not to ship it. That’s not what you want to do. You want to be providing value and impact to your customers and business through planned and well-thought out processes.
Rob Zuber is CTO of CircleCI, a continuous integration and continuous delivery platform.