how we abandoned the framework that permeates all development – and survived

My name is Mikhail Kuznetsov, I am a product owner in a team that develops the internal development platform Mindbox. In this article I will tell you how we abandoned the legacy framework that permeated all microservices. And we were convinced that such a transformation is feasible even in a company with 100+ developers and 1000+ corporate clients.

What is this framework and where did it come from?

Mindbox is a cloud-based marketing automation platform. Marketers use it to send newsletters, set up bots, widgets and banners, and implement loyalty programs. In 2008, we had few clients, and we hand-wrote code for every new feature: from promotions in the mailing list to discounts on the website.

A year later, there were four times more clients, and we began to think about how to automate the development of features. To reduce manual labor and automate typical actions, we wrote a base around which customization can be built. We called this base a framework.

The framework was supposed to take care of all issues not related to writing business logic: working with the database, validation, serialization, error processing and categorization, and 20 other aspects. Quite quickly they started adding everything to it, including tools for building admin panels – accounts/permissions, ui elements, etc., which is certainly not universally necessary in every service.

For a long time, the framework developed and made development easier. But over time it became too big and began to interfere.

When the framework began to cause problems

Initially, the framework ran on .NET 4.8. In 2021, this has already become a terrible legacy – we switched to .NET Core and ported the framework to it. At this time, three problems became acutely felt:

1. The framework has become a bottleneck. Developers often had to make changes to the framework, and each time it was painful. The version was constantly updated, it was necessary to update the changes. If several people worked at the same time, a war of edits began. And then someone made incompatible edits, and everything had to start all over again. As a result, developers spent up to 4 hours a day just to upload changes to the framework.

2. Microservices had difficulty working with a monolithic framework. At some point, the framework turned into a library of several tens of thousands of lines. When it was used in a monolithic service, everything was fine. But when we switched to microservice architecture, this became a problem.

It got to the point of absurdity: the microservice itself fits in 1000 lines, but behind it is a framework of 50,000 lines. For example, you need to make a trivial microservice: without a database, Redis and working with a bus. But the framework cannot do this – it must start from a configured database and asks for this poor Redis microservice. And if there is no Redis, then it crashes at the start.

Instead of speed and feedback loop, we received from microservices almost the same as from a monolith.

3. It was difficult to hire people. Developers want to work with new technologies and adopt in-demand experience. But our framework is not about that at all: new people had to learn from us something that would not be useful anywhere and would not increase their value. Because of this, our attractiveness as an employer decreased and conscientious specialists refused to come to us.

How we started fighting the framework

While the framework was tormenting the development of Mindbox, I managed to quit and work for another company. I saw a world without a framework and legacy, and in 2021 I returned to Mindbox with the determination to change everything.

I suggested decomposing the framework into separate small solutions for each need: for example, your own tool for working with configs, for deployment, caching, and migrations to the database.

The idea was great and everyone recognized it. But unattainable: we couldn’t stop the development pipeline to move everything from the framework. There was no understanding of how to safely “eat an elephant in parts,” and the whole elephant looked scary. Moreover, investing in a crude idea is a risk that we could not afford: suddenly there would be no suitable solution for the next problem.

The first refusal did not stop me, and I began to work on the idea on my own. I wrote down a list of tasks that the framework helps to cope with. For most of them, we managed to find solutions that any developer on the market can use: from the open source community, Microsoft or other suppliers. I added the missing ones in separate libraries with API documentation and a normal scope.

When I had enough tools to launch a basic microservice without a framework, I made a second pass to “sell” the idea to the team. This time I was assigned two junior developers to help me. Together we developed the first microservices without the old framework – the simplest ones in terms of the necessary infrastructure and libraries.

When we proved that it was possible to work without a framework, our colleagues began to take a closer look at our solution. Gradually, the teams abandoned the framework and together we created a pool of tools to replace it. For example, when validation was required in a microservice, they found a well-known library – FluentValidation. If a known solution was inconvenient, they made an adapter, for example, MindboxValidation based on FluentValidation – under the hood there was a technology that everyone on the market knew how to work with, and outside there was a familiar API.

In less than a year, we began to make all microservices without a framework. New features were battle-tested, proven to be effective, and so people were willing to use them. And if there was not enough solution for some problem, then it was faster to find a solution than to drag out a framework.

The replacement framework was called “aspects of a common platform” - this is a list of tasks and solutions that we agree to use

The replacement framework was called “aspects of a common platform” – this is a list of tasks and solutions that we agree to use

What we got by abandoning the framework: satisfied employees and 70+ new microservices

Development has become more productive. Without a framework, it has become easier to launch new microservices. From 2010 to 2022, we wrote 100+ microservices. Of these, 70+ were written from mid-2022 to 2024, when we abandoned the framework.

Microservices are faster. In parallel with the abandonment of the framework, we moved to Kubernetes. Its peculiarity is that it constantly raises many small pods with microservices. Pods with microservices on the framework took a long time to start, say, ten seconds or more, but without the framework they began to rise literally in a second. The tests have also become easier – they go faster without the legacy body kit.

Easier to hire and onboard employees. Now we don’t invite people to work with Legacy and don’t scare away smart candidates. In addition, before, newcomers had to be trained to work with our framework – now all solutions are up-to-date, and onboarding has become easier.

Satisfied developers. We conducted a survey among developers to find out how they evaluate the effectiveness of their work. Teams that abandoned the framework had a satisfaction score of 8.7, while those that stayed with it had a satisfaction score of 5.

Monolith developer results

Microservices Developer Results

The main thing that I myself took away from this story is that you don’t have to be a CEO to make decisions that simplify the life of the team and bring profit to the company. You can start making changes with yourself, get a small result and use it to get feedback and support from your colleagues.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *