Whenever you bring together a group of people and ask them to align behind a common goal, there is bound to be the occasional conflict.
As a team grows, the potential for this only increases. Already-stressful projects can become even more challenging when interpersonal challenges compound the technical ones. As a tech lead or manager, it’s important to be able to recognize conflict on your team early, and start to take steps to mediate it or at least limit the impact on your colleagues and on the project as a whole. The biggest difference between a team that falls apart due to their differences and one that’s made stronger because of conflict comes down to how that conflict is managed. Let’s take a look at two specific examples of this in action.
A project behind schedule: adding fuel to the fire
At a previous job, I was able to witness one of the biggest projects in the company’s history. This project was also one of the more complex projects we had taken on, while being high visibility with a relatively tight timeline. Because of all these factors, as well as some difficulties on the client side, this project was falling farther and farther behind the initial deadline that had been set, adding to everyone’s stress in the process. To combat this, the project management team began to explore the option of adding more developers to the existing team in hopes of accelerating the pace of development. However, when adding to the project team, the new members always have a period where they’re ‘spinning up’ before they can be fully productive. In addition, they do not have the context that the existing team has developed over the previous weeks or months of work, which can cause them to explore solutions that are less than ideal. And it was exactly in this lack of context where we started to see problems as we scaled up the team.
Dogma vs. deadline
One of the main clashes we had on this particular team was between the primary frontend developer who had been working on the project since the beginning, and one of the new developers who was just getting added to the team.
There was a particular function that was proving to be a major performance bottleneck. Because of the complexity of the site being built, this function needed to take into account many facets of the products on the site and return only a given set. However, the developer coming into the team lacked this context and all these feature requests that had stacked up over months, and wrote a ‘more streamlined’ version of the function that just went into the database and grabbed a group of matching records. When presented with the fact that he was ignoring crucial functionality and that this feature would never get past the initial stakeholder review, his counter-argument was that it was faster (which it was) and that it was done.
In this scenario, there wasn’t a clear case of one developer being right and the other being wrong – although each thought they were in the right. The developer who had been on this project since the beginning was focused on creating layers and layers of abstraction that made the code infinitely flexible in the long run, but not in a way the client had asked for yet. This turned out to be a detriment to the load time of the site as well as the overall timeline of the project; whereas the new developer was extremely focused on shipping features quickly, but ignored key client requests and constraints associated with the overall build.
The way forward
In this case, a compromise was required. The new developers on the project were able to take a step back and walk through the existing codebase with the existing developers, understanding more of the context surrounding the project as it had been developed up to this point. We all agreed that we couldn’t reject existing code as ‘unnecessary complexity’, but instead had to see to understand that there was probably an underlying reason for the choices that were made. At the same time, we were able to push the existing developers to simplify the code going forward to allow us to get closer to being on track with the timeline and budget of the project.
By having frequent project check-ins and the new engineers developing lists of questions that could be batched to facilitate this knowledge transfer, the current team and the new team members quickly got on the same page. And in the end, once we better understood the overall context of the existing codebase, we were able to split off onto different, discrete sub-projects. These projects supported the main development of the site but didn’t bring us into direct contact with the main codebase or the changes happening there.
A tale of two teams
Team dynamics get even more complicated when the teams being integrated don’t work for the same organization. For example, on a past project we had an agency-side development team working with a client-side product team on a large-scale migration and replatforming. The project was running relatively smoothly until we got into crunch time where the agency team was on site with the client-side project team. In this case, the main conflict was between a developer on the client-side team and one on the agency-side team.
The straw that broke the camel’s back
As silly as it sounds, what initially kicked off this conflict was a version control system that was causing code to be overwritten by subsequent changes. This caused confusion among the project managers and quality assurance team who were trying to verify tickets had been completed, as well as causing developers to look more deeply at the code that was being written by other members of the team. This caused some of us on the agency-side team to try and address a bit of ‘cowboy coding’ that was happening. We wanted to make sure we weren’t introducing a ton of technical debt purely for the sake of a launch. However, some members of the team chose to address this by exploiting the lack of enforced version control and rewriting work they didn’t approve of.
This, understandably, raised tensions when discovered, as well as made the two teams suspicious of each other. The agency-side team lost credibility with the client and because of this particular developer’s refusal to negotiate with the other side, in many ways the project was never the same. We did attempt to reconcile this with the client-side team, but because of the breakdown in communication and the fact that the incentives were misaligned between the client-side developers and the agency-side developers, tensions remained relatively high for the remainder of the project.
The way forward
In this particular case, the only way forward was for these two developers in particular to not work with each other anymore. In the end, we had to make a personnel change. No matter who was right, the relationship was too damaged to continue and a developer was moved off the project in favor of a fresh team member. That team member was well briefed on the situation so that they could handle the conflict more readily. What started as a simple lack of communication led to opinions and positions being entrenched, which eventually led to the team breaking down instead of emerging from the conflict stronger. This just reinforces the fact that frequent initial communication is important to make sure everyone is on the same page when a conflict starts to develop.
What can we learn?
In both these cases, conflicts were caused by a breakdown in communication and the failure to address this breakdown soon enough or intensely enough. It’s very rare that conflict goes away on its own. However, getting involved early in the process can help a solution be reached faster and can make the team stronger because of it. As we saw in the second case study, it doesn’t always work out that way, but that’s also why having the right people on the team, and helping to communicate to them that everyone has the same end goal, is important.
If possible, when doing this sort of conflict resolution, it’s helpful to have a third party who is knowledgeable enough to understand the various opinions in the debate, but not actively involved in the debate themselves. Developers, in general, are a pretty opinionated group, even about small things, and having someone who already has taken a side or has an opinion can make seeing things rationally more difficult.
Conflict is natural in teams, but a solid and well thought out conflict response doesn’t always come as easily. By detecting the potential for conflict early and either removing the landmines that could cause problems down the road or over-communicating when conflict has already arisen, you can make your teams stronger with every project you take on and every challenge you overcome together.