Reintroducing engineering thinking in the development world
At Qonto, we strongly believe that the success of our company will depend on our capacity to grow people and develop their hard skills. For tech teams, it means developing engineers and engineering culture. This article is about how we try to do it at Qonto, by giving our developers the time they need to have real engineering thinking.
Imagine you have to build something complex, a car or a house, what would be your first move? Grab a wrench, a hammer and start building it? Or will you first take a pen, try to understand the whole complexity of what you will build, draw a schema, make a plan and only start the construction part once all the engineering problems are solved? I bet you’ll choose the second option.
All good engineer knows it: you should use the pen before the tool! And it’s even more the case when the system you are working on is becoming more complex. This is true when you are an architect, a car engineer or a web developer.
Indeed, when your company grows, your software complexity grows, your team becomes bigger, the potential consequences of introducing a breaking change becomes way more important. Very soon, a feature that once was pretty simple to ship becomes a real engineering challenge, and you need deep conception thinking before you start developing it.
Unfortunately, after having worked with a bunch of technical teams I often saw the same pattern happening again and again: developers are fed with features specified by a product manager and then asked to slice it and start developing it right away. No time for conception, only for delivery.
At Qonto, we are building a Bank. This is a real engineering challenge and having this kind of “counter-engineering” culture would be suicidal. That’s why we decided to define our own way of building features and this is the main topic of this article: how did we reintroduce real engineering thinking in web development at Qonto?
What happened to the engineering culture in web development?
Of course, there is a lot of good engineering thinking in web development, but the overall engineering culture in our world is way lighter than what we can find in “old industries” that we too often look down in our startup ecosystem. In my personal opinion, the root causes are two folds:
- The Agile Methodologies Tsunami.
- The dangerous generalization of the idea that doing studies and learning theoretical knowledge is useless to become a good developer.
The negative impact of Agile Methodologies on engineering culture
Let’s be clear, the spread of Agile methodologies during the last 15 years brought a tremendous amount of value to the software engineering world, no question about that. Mainly because they offered an alternative solution to Waterfall project management that could be summarized as follows:
- Define an incredibly large scope, like rebuilding a whole back-office for thousands of employees.
- Start a months-long conception phase and deliver a ton of unreadable technical documentation as output.
- Engage in a year-long development phase and deliver an unusable, buggy product with years of delay.
On the other hand, Agile methodologies gained its popularity based on the following concepts:
- Reduce your scope as much as possible (with the “ship-a-MVP-first” mentality) and “iterate” on your product.
- Develop a phobia for technical specification and documentation that is coined as “bureaucracy”.
- Engage in development phases (“sprint” in the Scrum world) of one or two weeks.
And the second step is where the problem lies. Because Agile methodologies drastically reduced the scope of the development work, it also completely got rid of the technical conception phase.
The classic Agile tech team will have the following behavior: during the ceremony, the team has 1 to 3 hours to understand a feature, slice it into user stories, story-point them and get ready to develop it. Right after the ceremony they open their text editor and start coding because they have a number of tickets/points to put on done.
And it always ends up the same: they start coding, they bump into technical issues they did not anticipate, it changes everything in the way they need to implement the feature, they restart from scratch, bump into another issue, etc… And the most dangerous thing is that we coined this kind of waste “iteration” when let’s face it, it is pure bad technical conception.
Hence, year after year, we created the conditions where developers are pushed to code first and think later.
Of course, this was not the original intent of Agile methodologies. For instance, the first wave of Agile, led by the Extreme Programming movement, was completely focused on engineering practices and make better engineers. You can have a look at the cornerstone books of this movement: “The Pragmatic Programmer” (Andrew Hunt, David Thomas) and “Design Patterns: Elements of Reusable Object-Oriented Software” (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) where the focus was on building clean and reusable code, alongside resilient and well-thought architectures.
But the emergence of SCRUM for instance completely changed the way Agile methodologies were approached and they became a simple management tool that got rid of engineering practices — mainly because managers were not able to understand any of these practices.
“School is useless, you only learn theoretical knowledge”
I don’t want to sound reactionary, but in the tech ecosystem, I can hear more and more people saying that going to university is useless because you only learn theoretical knowledge, until a point where it became a joke (see this “Silicon Valley” extract). Of course, you can become a good engineer without a diploma (and I saw plenty of good examples), but you cannot become a good engineer without strong theoretical knowledge and the ability to work with models.
Developing and mastering models is the key that allows you to quickly navigate between different complex situations and gives you the capacity to abstract your work. And this should not be a replacement for the “learning by doing” philosophy, but an addition. Years ago, my TPS sensei (read this article if you want to learn more about Qonto’s culture) told me about his theory of knowledge. Whether you want to learn something new or run an experiment to prove something, you always need three things:
- A theory (e.g an equation or a standard)
- Experiment (e.g a test in a laboratory or repetition of a specific gesture)
- Feedback (e.g a measurement tool or a coach)
Let’s say you want to lead an experiment to define Earth’s gravitational acceleration. You will need:
- An equation: F=G*m1*m2/r²
- An experiment: in a controlled environment, without air friction you’ll drop objects — let’s say an apple.
- Finally, a way to measure the time it took to the apple to hit the ground and check if the equation was true — is Earth’s constant indeed 9.8 m/s2?
Now let’s say you want to learn how to do a proper service in tennis. You will need:
- A standard: what is the best-known way to do a service? You need to throw the ball that high, jump at this specific moment…
- Repetition: you’ll have to do 100 services.
- A coach, that tells you if you do it well and what you need to improve.
Same goes for code:
- Theoretical knowledge on how things work (why should I use a float instead of an integer? What’s the difference in terms of memory mapping and what is better suited to my situation?)
- Experiment: I should code and learn by doing.
- Feedback: senior devs that help me understand where my practice is not good, via code pairing and code reviews.
If we want to summarize, let’s look at it this way:
If you only think about “learning by doing” without models then you’ll end up having a pure “trial and fail” approach. As Bertrand Russel would put it, you’ll be nothing more than an inductivist turkey.
To become a strong developer you indeed need to learn by doing but also take time to deepen your theoretical knowledge. And of course, you need senior engineers that help you grow by giving you feedback.
How do we reintroduce engineering thinking at Qonto?
At Qonto, we try to approach things differently and we aim at giving time to developers to have some real engineering thinking. We do that thanks to something we call a dive-in, a phase that is mandatory in our development flow and consists of using the pen before coding.
What is a dive-in and how does it work?
What we call a dive-in at Qonto is a phase in our feature development process between the specification phase (what is the product problem we are trying to solve and what is the functional solution we propose) and the development phase (where we slice the work in small tasks and start coding).
This phase is mandatory and is a time when developers only dive into the code base, think about the way they want to technically conceive the feature, about the implications of what they are going to do, answer all the problems they might face, go talk to other stack teams, do a POC if needed…
During this phase, they need to answer questions such as:
- What will my endpoint look like?
- What will be the error responses?
- Is there any refactoring I should do during the development of this feature?
- Do I need to implement idempotency mechanisms?
- Do I need to create a new service?
- What will be the implications for the rest of the system?
Once the conception is done, the devs then push a merge request to the team explaining what they want to implement with diagrams, schema, images, pseudo-code or concrete examples of what modifications they want to implement (e.g which fields I am adding to a database with corresponding types). This solution then needs to be validated by the members of the team. Only once this process is done, then the developer starts coding.
This practice is for us a great way to:
- Insure devs had the time to think deeply about the conception before starting anything: “using the pen before the text editor”.
- Coach junior and intermediate devs on architectural and complex engineering issues
So, how long does it take to do this technical discovery? Well, these dive-in are not timeboxed — each dev decides how much time they need to do a proper conception. To give you an idea a dive-in can last from 1 hour for very simple implementation to 2 weeks for complex work. We consider it as done only when developers are clear on the plan they will follow and are able to split their work into small tasks.
Of course, at first, implementing this kind of culture is not easy. You’ll face a lot of issues and resistance including:
- Developers debating for too long over an implementation (but this actually brings value to the team, up to a certain point).
- Resistance from some of the most impatient engineers that will tell you “I already know exactly what needs to be done”.
- Suspicion from the business side wondering why you want to spend that much time thinking instead of coding.
But if you go this way with conviction it will bring you an enormous amount of value.
What are the impacts of introducing a dive-in phase?
Quality and speed
Of course, at first, this initiative might sound crazy in tech companies where time is at the essence, and where investing time upfront is often seen as a waste of time. But actually, you will win a lot of time because you will gain in quality… and velocity.
Indeed, after the introduction of the dive-in phase, we noticed a large decrease in reworks we had on features after shipping them. We went from a situation where a lot of features shipped needed to be reworked to solve bugs (rings a bell?) to a situation where when something is shipped, it most of the time works right-first-time. This, of course, increases your velocity (you don’t have extra work to do after the feature is done), improve your quality (fewer bugs and thus happy customers) and finally the trust in the work you do. Next target, having so much confidence in what we do that we get rid of the “do not push to prod on Friday” philosophy.
But it also has a huge impact on development time because when you have thought deeply about your conception before coding then… coding becomes quite easy! Here is the impact of dive-in introduction in our total development time on features after 3 months:
As you can see, it helped us to drastically reduce the time it takes us to ship a new feature, including the time of doing the dive-in: in 3 months, we almost divided by two this metric.
Bottom-line, giving time to your devs to do some proper engineering thinking is not just a philosophical stand. It has a strong positive impact on your business and on your customers.
Why you should care about it as a tech leader? Make people grow and feel proud.
Of course, this is great to see a direct positive business impact. But above all, it is a way for us to make people grow at Qonto and make the team passionate about its work. Instead of creating a dynamic where developers are pushed to ship code as fast as possible and fix it when it’s on production, you lay the ground for an environment where they can be proud of what they ship and trust the quality of their work.
Of course, everything is not perfect and we sometimes fall again into the trap of not investing enough time in conception — and sometimes the opposite. But as a team, we are learning on a daily basis how to do better technical conceptions and, bottom-line, how to become better engineers.
In our perspective, this is what will make a company prevail: invest in the people, give them the time and space they need to think about how they can become better at what they do, and they will make your company grow.
You want to work in this kind of environment? We are hiring! https://qonto.eu/en/careers