When Helping Creates More Work: Why Adding Developers Slows Down Projects
When Helping Creates More Work: Why Adding Developers Slows Down Projects
Why adding developers to a project doesn't always make it move faster, and how shared context prevents duplicated work.
·Updated on:··
Get Practical CMS Decision Briefs
Get concise advice on choosing the right CMS, understanding migration costs, and avoiding expensive implementation mistakes before they become roadmap problems.
Why adding developers to a project doesn't always make it move faster.
A client wants to speed up a website project.
They have additional developers available, so they bring them in to help.
The new team looks at the codebase, finds several unfinished pages and starts implementing them. A few days later, they have working components, functional interactions and something tangible to demonstrate.
The client sees progress. The new team feels productive.
Meanwhile, another developer has been working on those same parts of the website.
They haven't finished the pages yet because they're still deciding how the components should fit into the larger system, which elements should be reusable and how the data should flow through the application.
The new team doesn't necessarily know that.
From their perspective, they've simply picked up unfinished work and helped move the project forward.
Eventually, the two implementations need to come together.
That's when everyone discovers that some of the work has been done twice.
Now the team needs to compare implementations, reconcile conflicting changes and decide which parts to keep.
Nobody necessarily did anything wrong. Everyone was trying to help.
But adding more hands may have created more work than it eliminated.
Everyone has a reasonable explanation
What's interesting about this situation is that it doesn't require anyone to be careless or incompetent.
Consider the client's perspective.
They have a project to deliver, a deadline to meet and additional development capacity available. It seems reasonable to put those developers to work rather than leave them idle.
More people should mean more progress.
The additional developers have an equally reasonable perspective. They see unfinished work, recognize an opportunity to contribute and begin implementing it.
They're not trying to interfere with anyone else's responsibilities. They believe they're reducing the amount of work remaining.
The existing developer sees the situation differently.
They might be working through a deliberate implementation sequence, establishing the component architecture before connecting real data, or waiting for certain dependencies to be resolved.
The components that appear unfinished to someone else may already be part of their plan.
Each participant is acting on a different understanding of the project.
And because each perspective makes sense independently, the problem can remain invisible for quite some time.
Everyone can be making progress individually while the project is becoming harder to complete collectively.
Unfinished doesn't mean unclaimed
This is where things become particularly subtle.
When we join an existing software project, we tend to look for gaps.
A page is missing. A component hasn't been implemented. An interaction doesn't work yet.
These appear to be opportunities to contribute.
But an unfinished component can mean several different things.
Perhaps nobody has started working on it.
Perhaps someone has started but hasn't pushed their changes yet.
Perhaps its implementation depends on another feature.
Or perhaps it has deliberately been left unfinished because its architecture or data requirements haven't been established.
Those situations can look almost identical when you're browsing a repository.
Imagine a developer working on a product listing page.
Before completing it, they want to understand how product filters should behave across different websites, which components can be shared, and how the content management system will provide the necessary data.
They might temporarily use placeholder data and leave certain interactions incomplete.
Another developer sees the unfinished listing page and decides to help by completing it.
They implement the filters, connect the data and create reusable components based on their understanding of the requirements.
The result might be technically sound. It might even look exactly as intended.
But it may not fit the architecture the first developer was preparing.
Now the project has two interpretations of the same feature.
As I break down in Vertical Slices: Stop Starting From Scratch, component architecture succeeds when teams agree on abstraction levels—from UI primitives to shared templates—before implementing redundant one-offs.
What appeared to be a gap in execution was actually a gap in shared context.
The solution isn't to discourage developers from taking initiative. It's to make the state of the work visible enough that people can distinguish unclaimed tasks from deliberate sequencing.
More output isn't necessarily more progress
Software projects often measure progress through things that are easy to see.
These are useful signals, but they don't tell the whole story.
A client might see five newly implemented pages and reasonably conclude that the project has moved forward.
The developers who implemented them might report that their assigned work is nearly complete.
But if those pages overlap with another implementation, some of that progress may need to be reconciled before it can contribute to the final product.
The additional work might include comparing two component structures, deciding which implementation to retain, resolving conflicting changes and adapting existing functionality.
None of that necessarily means the original work was poor.
It simply means the work wasn't independent.
This distinction matters because adding capacity to a project only increases throughput when the additional work can actually be combined with what's already being done.
If two developers implement different, independent features, their contributions can be complementary.
If they independently implement the same feature, the project doesn't automatically end up with twice the progress.
It might end up with two solutions and a new integration problem.
And the cost isn't always obvious.
Two implementations may merge cleanly at the Git level while still containing duplicated logic or incompatible architectural assumptions.
Conversely, a difficult-looking merge might turn out to be straightforward once the developers compare their work.
You often cannot establish the actual extent of the problem until you examine the implementations together.
That's why visible activity should never be confused with guaranteed progress toward the final deliverable.
The misunderstanding can happen before anyone writes code
The obvious lesson might seem to be that teams should communicate more.
But communication alone isn't necessarily enough.
Imagine a technical lead explaining their implementation approach:
First, the existing frontend will be reorganized into reusable components. Then those components will be connected to the content management system. Finally, the styling will be optimized.
The lead recommends postponing additional styling work until the components are in their intended structure.
But different people may interpret it differently.
The client might understand that the technical lead is handling the CMS integration while another team can work on the frontend.
The additional developers might understand that they should begin converting the frontend immediately, including bringing components into the production repository.
The technical lead might believe that the other team will wait or work independently on styling in the original design repository.
Nobody necessarily realizes that they're operating under different assumptions.
A written recommendation is valuable because it creates a shared reference. But sending a message doesn't guarantee that everyone has understood it, agreed with it or changed their plans accordingly.
A recommendation is not the same thing as a decision, and a decision is not the same thing as shared ownership.
For work that crosses team boundaries, it's worth making those distinctions explicit.
What has actually been decided?
Who owns which part of the implementation?
Which areas should remain untouched?
What dependencies need to be resolved before work continues?
And when should the teams bring their changes together?
These questions may seem administrative, but their answers can determine whether additional developers increase delivery capacity or create additional integration work.
What happens when you discover the overlap?
Suppose the work has already been done.
One team has completed several pages. Another has implemented overlapping components. Both have invested meaningful time.
At this point, insisting on the original plan isn't necessarily the most productive response.
The original approach may have been well reasoned, but the project is no longer in its original state.
There is now completed work worth considering.
The immediate objective should be to understand what actually exists.
Get the implementations into a common working environment. Compare the changes. Identify which components overlap, which can be reused and which require further work.
Some changes may be straightforward to integrate.
Others may require architectural decisions.
And some implementations may be sufficiently different that the team needs to choose one approach rather than attempting to combine both.
The important thing is to make those decisions based on the actual work, not assumptions about what the conflicts might be.
This is also where it helps to separate the technical problem from the interpersonal one.
The discussion doesn't need to become a debate about who should have done what.
A more useful set of questions is:
What can we preserve? What still needs to be done? How can we avoid introducing further duplication?
Once the current implementations have been reconciled, the team can establish clearer responsibilities for the remaining work.
Perhaps one group completes the presentational components while another handles data integration.
Perhaps the developers divide the remaining pages between them.
Perhaps a particular architectural decision needs to be resolved before either team proceeds.
The arrangement depends on the project.
What matters is that everyone is now working from the same understanding.
When a plan encounters reality, the objective isn't to defend the plan. It's to find the most practical way forward from the situation you're actually in.
Give people something to review before asking them to decide
There's another complication when multiple teams work independently: they may encounter each other's work for the first time during a meeting.
A developer shares their screen and demonstrates several completed pages.
The work looks promising.
But the person responsible for integrating it hasn't examined the code, compared the branches or understood the architectural decisions behind the implementation.
They can comment on what they see, but they cannot responsibly assess everything that matters.
A working demonstration tells you that an implementation can produce a particular result.
It doesn't necessarily tell you how that result was achieved, whether the implementation fits the existing architecture or how much work will be required to integrate it.
Those questions deserve time and attention.
For substantial technical decisions, I prefer to examine the implementation asynchronously before discussing it.
Share the pull request. Explain the approach. Identify any decisions that need input.
Give the other developers an opportunity to review the actual changes and consider their implications.
Then, if something remains unresolved, use a focused meeting to work through it.
This doesn't mean avoiding meetings. It means making them more useful.
A meeting is a much better place to resolve a specific architectural question when everyone has already had the opportunity to understand the problem.
And whatever gets decided should be documented afterwards so that people who weren't present have the same reference.
That last step matters because the problem we're trying to solve is not a shortage of conversations.
It's a shortage of shared understanding.
More hands need more context
Adding developers to a project can absolutely accelerate delivery.
There are countless situations where additional capacity is exactly what a project needs.
But bringing in another team isn't simply a matter of giving them repository access and pointing them toward unfinished work.
They need to understand the implementation plan, existing ownership, architectural boundaries and the decisions that are still unresolved.
The existing team needs to understand what the new developers will be working on.
And the client needs visibility into how those contributions fit together.
None of this requires heavyweight processes or endless meetings.
It might be as simple as a shared task list, clear ownership of components, regularly integrated branches and explicit acknowledgement of important technical decisions.
The goal is not to control every action or discourage initiative.
It's to make sure that initiative contributes to the same outcome.
Because the most expensive misunderstandings are not always the ones that stop people from working.
Sometimes they're the ones that allow everyone to keep working, confidently and productively, in different directions.
And by the time anyone notices, there's considerably more work to reconcile.
The next time you're considering adding developers to accelerate a project, don't ask only how much additional work they can produce.
Ask what they can own, what they need to understand, and how their contributions will fit into the work already underway.
More hands create more capacity. Shared context is what turns that capacity into progress.
Related Reading & Engineering Management
For more on team coordination, architecture sequencing, and delivery frameworks: