One of the biggest mistakes that folks make a lot of times is letting people linger on for too long. Hiring good engineers is hard and getting new folks up to speed is hard. You feel like you are going to miss your product delivery plan if you let someone go.
Letting folks linger when you are unhappy with each other creates a toxic environment. This toxic environment is generally contagious and brings the entire organization down. Of course you can’t have a constant state of euphoria on your team, but if a productive and pleasant environment is not there the team is in trouble.
Constant visible underperformance on the team is going to lower the bar. This lower bar is going to make it hard for you to manage performance. Having a “C” player on the team is going to make it hard to get the “B” performance up. It basically sends a signal of tolerance towards mediocre performance and it will be hard to get out of that tail spin.
Last point is that some top performance are very much in tune with toxic environment and bad performers. They might feel like they are shouldering a bigger load than they should. They might also feel like they are on a losing team and should entertain some opportunities to join a winning team elsewhere.
it’s especially hard to deal with this type of the situation when underperforms are not combative - they are looking to improve and they try, but they just can’t get the job done. It takes precise expectation management and frank conversations to tell people what’s expected out of them.
I’ve provided generous compensation packages to let people go if they weren’t working out. At the time I am writing this (beginning of 2017) Software Engineers have not had a big problem finding other jobs. Almost always when the engagement or performance wasn’t there - letting people go was the right thing for both parties. The right question to ask before you arrive at that decision is: “are we helping each other or do you want to get out.”