Bring back the monolith

Angel Paredes
The Glovo Tech Blog
7 min readNov 21, 2022

Nobody would call me crazy if I state that most companies, that have reached a certain size, have moved from monolith to microservices (and very few of those probably challenged the decision). This story starts in one of those companies.

In the past years, I have been heavily focused on the front-end side of software engineering. The company where this brief story takes place had a web application with more than a hundred contributors across 15+ teams whose domains spam the whole company product.

We used to host different committees and workgroups to help us identify issues within the global scope of the application and align on solutions. Needless to say in such forums there were discussions and debates among those which different stances.

I especially remember one of the contributors with whom I used to have long arguments. It is not about who was right or wrong (in software engineering there is rarely an absolut answer), we just had different points of view on how to move forward with a certain solution, and at times it even seemed like a conflict.

After some time, it was not a coincidence, that with the growth in complexity of clients (both mobile and web) these monolithic applications have moved towards modularisation, micro frontends, and some other architectural approaches that help siloing development efforts across teams (with the flexibility of scaling by need). And when the time came, modularisation of the web app happened. Committees stop being needed as everyone could work decoupled from each other and the platform team will just continue working on features for the microfrontend solution.

I was happy teams were finally able to be more autonomous, decoupled, and such things. My silly younger self was, in a way, relieved that he won’t need to debate with the other contributor to proceed with the product roadmap… And I was wrong.

The monolith that brought us together

In the beginning, the silence was fine, it seemed productive and people were delivered at a great speed. But at what cost? One day I needed a feature around authentication and I thought that maybe a team out there has already worked on it. I found that not only 1 team had a solution, but that we had 4 solutions and a WIP around the same problem. I decided then to dig a bit more.

Next, I saw that a solution I decided upon came with several edge case issues that I did not even think about, not only this, the contributor with whom I used to argue had a more solid implementation but lacked some optimizations I added to mine… It was then that I realized a couple of things: A silent room means issues in the long term and that alignment is as important or more than autonomy.

Dilbert’s Alignment vs Autonomy Graph. We would love to be in the top right corner

Could this still happen even if we never split? Yes, no doubt, but it is also true that a monolith gives us for free some incentives to use some alignment and communication “patterns”:

The Neighbour Pattern

Friendly neighbor over-the-fence peeking

Whenever you are facing an issue, probably there are a few things as important as understanding context. Context is a tremendously powerful tool that can help us take decisions or understand how we got to the current state.

In a monolith, context is more easily shared than in a distributed approach. Just the fact of keeping a local copy of the monolith’s updates already gives you information about what parts are changing. If the context is important let’s mention as well the importance of discoverability.

When coming up with new features we often discover that we are not that creative when it comes to naming things (and that’s great), and we will already find similar solutions/features around our codebase just with a simple search by name.

The neighbor pattern shows how easily context and information comes to you when you are adjacent to it.

The Common Enemy Pattern

“And the enemy of my enemy is my friend.” — Dwight Schrute

Sadly enough, shared “hate” is one of the easiest ways of putting people together. In the end, when looking for affinity and alignment you seek points in common between the concerned parties to build from there. Well, having the same set of problems is a good point to start at.

Monoliths come with pains (maybe more than other approaches) and the fact that those problems affect everyone equally is a great argument for finding alignment fast to tackle such issues.

The common enemy pattern highlights the importance of understanding shared problems so that teams can work together against them.

Conway’s law and communication patterns

Not familiar enough with Conway’s law? Let’s repeat it once more:

Organizations, who design systems, are constrained to produce designs which are copies of the communication structures of these organizations.

In a nutshell, a set of small distributed teams will (most surely) end up with a set of small distributed systems whilst large teams will produce monolithic systems. And, in my experience, companies that challenged this principle faced a gruesome amount of resistance, just because it felt unnatural.

So, what would happen with our systems if our organization has patterns like these:

John Cutler’s 10 potential Damaging Communication Patterns

Can you envision how systems will work together given bad communication patterns between teams? It is noticeable already when 2 teams never communicate but their services need to interact: incongruent APIs, redundancy, feature incompleteness… Let’s not mention the issues that will come up when there are more than 2 teams implied.

There is an undeniable correlation between social engineering and tech engineering that we cannot ignore, hence organizations need to consider those even more thoroughly than their tech decisions (since human changes take longer than tech ones).

Monoliths are not the solution

Ok, I must admit that the title was probably a bit clickbait-ish. Even though it seems that I favor monoliths over the microsystems approach, it is just because its easier to keep certain patterns there. What I really would love is for organizations to think better and support proactively communication channels that can supply the gaps between teams.

For example, one great way of doing this is through communities of practice. There are many shapes and structures to form a Community of Practice (CoP). In my opinion, healthy CoP adapts the agenda to the current need of the group, in the same way, problems change over time so it needs to change the way we decide to tackle them. In any way, there are certain topics and goals that a community would never have enough of:

- Conflicts. Bringing the enemy pattern to the picture, “I am facing this issue… am I alone?”, if it is not the only team facing the issue then the community can prioritize or brainstorm to solve it. On the other hand, if nobody else is facing it, they have more information about the root of their issue and maybe people would be able to help troubleshoot it. Don’t be quiet about issues, speak loudly about them, and make them normal (everyone has an issue), so that teams find a safe space to share and learn from them.

- Success stories. The end of a refactor? The team finally found the root of that memory leak issue. That silly log that created some noise for the last couple of days? Share it, I can’t emphasize enough the importance of sharing. The neighbor pattern is about sharing and the easier is for me to get information from my peers, the better. You never know what that may inspire, even if it only brings recognition to the team for their good job.

- Healthy network. Keep them unbiased, diverse, and open for people to join. Networking is a great tool to have and nobody should gatekeep it.

- Make sure that your community does not become a reporting tool. It is a place to give voice to everyone, participants must feel encouraged to challenge decisions, ask questions and take ownership. At the moment only one party has a voice, it mirrors one of those damaging patterns we spoke about.

Conclusion and last words

As a person entitled to take decisions over architecture, it is important to keep the social organization factor of the problem in mind:

  • Make sure that new communication gaps are covered with some other mechanism.
  • Anticipate the communication design and how it will change the balance of your organization.
  • Understand the role that different teams will play in such changes.
  • Finally, keep an eye (or better an ear) and make sure that your teams talk among themselves and with others.

Maybe we do not need to bring the monolith back, but surely we need the community of developers to stay and navigate the issues together.

--

--

Angel Paredes
The Glovo Tech Blog

Learnaholic (if that is even a thing). Software, in practice, is a holistic social engineering so let's try to get the full picture