If adding more engineers doesn’t speed up our development, what does?
The idea that hiring more developers will lead to faster time-to-market, is a common misconception.
If only it were that simple.
Instead, we should start with figuring out what’s actually going on, because software development is a complex beast.
There’s no rule of thumb here. There might be quick wins, but even those are highly situational and specific.
The solution to any given situation will be bespoke, but let’s say that knowing a few best practices helps.
Let’s go!
Respect Legacy Code & Treat it Right
Let’s say the team has inherited an undocumented, hard to discover and maintain mess, or is determined to call it that because it was ‘not invented here’…
It’s important to handle this kind of situation carefully, since you don’t want this allergic reaction of engineers to automatically lead to a full rewrite.
Yet this happens way too often, and it costs businesses a lot of time and money.
The way a company handles legacy code is a gauge of their maturity, so whereas that inexperienced scaleup team might be extremely tempted (and often not hindered) to do a full rewrite, the more seasoned the developers are, the less likely they will enter that path, and the more likely they will instead apply architectural patterns like Strangler Fig (Martin Fowler) to slowly and iteratively replace the legacy code.
You could say that all code that isn’t documented or has no tests, is in fact legacy. It’s not about age, it’s about readability and clarity.
Legacy code isn’t a technical problem. It’s a communication problem. — Andrea Goulet
Especially when the original developers have left, this becomes imminent.
Forget Technical Debt
Yes you read that right. Let me explain…
In “Forget Technical Debt — Here’s How to Build Technical Wealth” Andrea Goulet says startups need to shift their mindset away from paying down debt toward building technical wealth, and away from tearing down old code toward deliberately remodeling it.
So we have to get real about legacy. From a business perspective, it is just a better idea to have a continuous, iterative improvement effort that is an integral part of our software practice, instead of radical and risky big bangs.
In “Technical Debt is not a Technical Problem”, Dave Mangot says “Tech debt is also not inherently good or bad. Obsessively trying to eliminate all technical debt will almost certainly run quickly into the Pareto Principle where 80% of the debt is a result of 20% of the problem and trying to eliminate the last 20% of the debt is almost certainly not an economically prudent course of action.”
In short, technical debt is a permanent thing that shouldn’t be used as a swear word. Instead, it depends on the stage and complexity of a software product how it should be dealt with and what level is acceptable.
Own the Code in a Senior Way
You absolutely need one or two very senior, architect-like engineers that ‘own’ all existing code, and work from there.
I’ve seen teams with too little experience nearly drown, come up for air, only to shout ‘full rewrite!’, where that should not be an option until really, really proven.
A true senior will be able to analyze existing code and come up with ways to proceed, like adding tests, splitting and reorganizing for next steps, etc.
A more junior team will tell you that, if they touch one line of code to fix a bug, something might break, you know, because it’s all spaghetti.
It is extremely important to get an independent view on what the ‘entanglement’ state actually consists of, but let’s say that in most cases, disentanglement is cheaper than a full rebuild.
💡 TIP: Start with regression testing, so you control the situation, reduce fear, and make way for a less negative and biased look at legacy.
Split up the Monolith (in all ways possible)
Having a monolith — a single unit of deployment, makes working as a team harder. Not only do you have to know more as an individual developer before you can work on stuff. It can also be hard to work in parallel because of the dependencies within the monolith.
Modularizing the monolith (no, not creating microservices!) is a must, and will not only get the app in a better state, but also allow individuals to work on aspects of an app without having full scope.
Separating frontend from backend is a relatively easy first step.
Adding an API Gateway the second.
And so on.
More reading:
- https://awesome-architecture.com/modular-monolith/
- https://www.fearofoblivion.com/build-a-modular-monolith-first
- Microservices are overkill for 99% of startups!
Address the Documentation Problem — Intelligently
If there’s a high dependency on some lead’s knowledge in the engineering team, onboarding new developers becomes cumbersome.
This situation often goes hand in hand with these individuals having trouble adapting. They might have been the first employees, having had the full codebase under their responsibility. Letting loose, taking a different role, coaching and documenting might not be their main strengths.
Resolving this catch 22 isn’t always easy, but an essential step for the organization.
The lead described above being a key player in the pressure cooker of production, it is essential that someone looking at strategy (mostly the CTO — or a hired Fractional CTO) identifies the gap in knowledge, and helps these individuals download their brain into a digital, shared, easily accessible structure. A live Wiki is best suited for the purpose.
This documentation process should be done outside-in, starting with high level domain descriptions, use cases, architecture diagrams, infrastructural choices, important architectural decisions, base technologies, and pointers/deep links to other information, as you don’t want to duplicate information.
Also, such a Wiki doesn’t have to be beautified: it’s internal knowledge management, and any barrier of entry should be removed!
In a mature development environment, new recruits get a link to the Wiki, and can onboard themselves up to being able to contribute without heavy reliance on a senior/lead developer.
Examples of Live Wiki/Knowledge Management apps:
- Nuclino | Your team’s collective brain
- Notion — Your wiki, docs & projects. Together.
- Guru | Organize company information & access it anywhere | Guru (getguru.com)
- Slite — Your Modern Knowledge Base
Analyze & Fix the Product Development Process
How a company implements a formal development process is not dictated by the many books about the subject. Being flexible, adapting to your teams’ structure and needs is crucial, but there are ground rules:
- Be prepared for the unforeseen
- Be humbled. You mostly don’t even know what you don’t know, so forget about estimating
- Iterate in small steps. Test, validate, iterate again
- Try to be Lean at every step (no waste)
- Most time is lost in features nobody uses. Remember that. Use UX Research and Design Thinking Principles to prevent that.
Since this is a highly politicized and religiously activistic territory, I will leave you in the caring hands of such people as Paweł Huryn, Leah Tharin and Maarten Dalmijn for guidance.
When the best practices described above have been implemented successfully, the chances that hiring new developers will indeed speed up development, can be raised considerably.
But by that time, chances are also that you realize you don’t need your team to grow in size…