Clubhouse is now FREE with all core features, for up to 10 users! Learnmore

A cautionary tale on using microservices (when building software for others)

Peter Bex

Since a few years ago, the microservice architecture has been on the rise. As with every new paradigm, there's a hype cycle which starts with people jumping on the bandwagon left and right. This hype can lead to products being built on this architecture, even where it makes no sense.

We've now reached the point where the microservice architecture is better understood, and posts criticizing microservices have started to spring up as well. But some people use it to good effect, so it's not just "good" or just "bad." Perhaps you're considering a microservice architecture for your application. Let's take a look at when microservices make sense and when they are overkill.

Control is important

From my point of view, a microservice architecture is most effective if you're building a product you fully understand and control.

(Editor's note: Clubhouse broke up its monolithic backend application into several micro-services, and it works for us because we have control over how our application should operate.)

However, when you're building software for others, a microservice architecture may be more limiting in the future. One of the biggest challenges I've come across was when splitting up a bespoke monolith application for a customer. We had good reasons at the time: the monolith was written in a legacy framework for a legacy database, and we wanted to continue new development with a more current system. It was probably the right choice at the time, but there have been struggles!

Because you think there's a clean separation between two applications, you decide to split them apart. But then there will come a day when the customer asks you for a feature that requires tight integration between two or more applications. And you typically don't want to have to explain that you can't do it because of an architectural decision you made early on.

Example pitfalls

The simplest examples to understand are reporting and pagination.

For example, let's say you split user management and login into a separate application. Then, the customer asks for a report which is grouped by user role. This requires information from two separate applications. If they live in the same database, you can easily query it. But if that's not the case, you cannot efficiently join this information together. You could create a daily rollup and aggregate the information in a data warehouse, but that creates more work: now you have another database and set of scripts to maintain. And this won't work if the report needs to be on live data. Then you will probably end up with a lot of duplication of data in both systems, which blurs the lines of the system's responsibilities.

When you need to paginate over a filtered set of records, sometimes filtering happens on data in one application and the pagination over data in another application. You can only know which records end up on the page after joining them together.

Another example is lock-step development. If the line on which you split an application is not perfectly smooth, you will typically end up having to add features to two applications. Then these need to be carefully deployed at exactly the same time so that the data models fit. Alternatively, you would need to bend over backwards to support the "old" version and the "new" version of your API in either or both systems. This causes extra work.

Deployment and testing are also a lot harder, but these are things Martin Fowler acknowledges and warns against as well, stating "don't even consider microservices unless you have a system that's too complex to manage as a monolith".

When to use microservices

Nevertheless, even if you're writing bespoke applications where the customer is in charge, microservices can have a place. For example, if you're using Sentry for error tracking, that's what I would consider a microservice. It's not super "micro," but it's a dedicated system that does one thing and does it well. In another example, we were asked to build an address checking / auto-completion database for multiple customers. We have successfully split this off into its own service, which we can re-use for numerous customers. Occasionally, a new feature needs to be added, but that tends to be general enough to be useful for multiple customers. And even if it isn't, it won't get in the way for the existing users.

These kinds of re-usable nuggets are the dream of computer science, so if you recognize them, make use of it! But in general, if you write bespoke software for customers, I would be very wary of using the microservice architecture unless there is an excellent reason to use it.

Have any experiences to share on using microservices? Let us know in the comments!