Doesn’t pairing cost twice as much?
(I was recently involved in a discussion about pairing, and I think what I wrote will be of more general interest.)
Many teams evaluate pairing from a simple mathematical perspective.
Total work done = # of team members * amount of time spent working
If you want to increase the amount of total work done, then you either increase the number of team members or you increase the amount of time they spend working. Those are your levers.
Under that approach, when you add pairing, you end up with:
Total work done = (# of team members / 2) * amount of time spent working
Or, you only get half as much work accomplished.
As I’m writing this, I fear that you think that I’m create a caricature of teams, and that nobody really operates that way. Unfortunately, the sad truth is that the majority of the teams that I’ve worked on or worked with spend virtually all of their time working and almost none of their time figuring out how they might work faster. And, if a team works in such a fixed mindset, it’s not surprising that they think pairing is a bad idea.
There is a saying in the performance tuning world which says, “You can make small improvements by speeding up parts of your code, but the best way to make big improvements is by not doing things at all”.
This applies much more to process. So, let’s take a look at some of the things going on during the development process, and see what effect pairing has on them:
- Bugs are very expensive; you pay to find/document/track/triage/workaround/investigate/fix/verify them. I do not have any data at hand, but I wouldn’t be surprised if most bugs cost the organization a person-day, even if they are found by the development team. That is a lot of waste. Pairs are much better at finding bugs than singles.
- You can replace your code review process with something better. It is a long-held tenet that effective code reviews are a cornerstone of creating high-quality code, and to talk about changing that is heresy in a lot of places. Regardless of the fact that many groups that have an extensive code review process have crappy quality, and that tightening the review process generally does not improve that quality.
There is a technique known as code inspection where the code is inspected in detail by a group, and there is some research that shows that it works, but it is a hugely expensive technique. In reality, code review has a poor cost/benefit payback; reviews are not effective at detecting important issues and usually deal with superficial things like syntax. The basic problem is that it is too hard to get inside the thinking process of the person who wrote the code and figure out why they did what they did, and – even if you can do that – it’s expensive for them to go back and rework things.Perhaps one could come up with a way to do continuous code review. That would let you catch the issues up front, and since you could discuss implementation with the other people involved, you would not only catch more bugs but you would end up with better implementations overall that was understood more widely. And then you could reduce the amount of time code is waiting for review and the number of interruptions for people.
And yes, I just described pairing and mobbing. I don’t advocate throwing out your whole code review process; I think the pair working on the code can make a good call if they need other input before checking in. I guarantee that pairing + no additional code review will generate fewer bugs than individual work and deep code review.
If you are able to do this in your team, it is a game-changer. In many cases, you can pay for the extra cost of pairing through this change alone. Oh, and I missed one more benefit; this allows your developers to work on one thing rather than switching between them, which is a very wasteful and error-prone process.
- Developers hate being stupid and love finding things out. That means that we are much more likely to spend time researching something online and/or trying to figure out what a problem is than asking somebody. Hours of time. Put two people together, and the pair with both figure out things on their own more quickly and be quicker to ask for help when they can’t.
These are all important benefits, and I think they are enough to “pay for” pairing on their own. But, I actually don’t think they are the most significant benefits. The big benefits are at the meta level…
When I was a team manager in my early years, I had a number of hard problems:
- Suzy is the only one who knows the rendering engine well, but she’s on vacation next week and I suspect she is getting bored with working on that and may leave.
- Rick is a very good web developer, but right now the set of features that we are working on is heavily biased towards the server side, and I don’t know what to assign to Rick. Next month, I think I’ll probably have the opposite problem.
- Todd just joined the team and I’ve pointed him to our team onboarding and overview documents, but it’s out-of-date, and everybody is focused on their current task so he’s floundering a bit.
- Jill is my senior dev and has great design and TDD skills and knows a lot of ways to work fast. We’ve tried brown-bags for her to share this with the rest of the team, but they aren’t working very well.
- There’s a new project in a couple of months that the team will need to jump on, but nobody currently on the team has the relevant experience.
- etc.
Nearly all of these just melt away if my team is pairing often. Knowledge transfer happens quickly and easily during pairing, and everybody gets more versatile and better at their jobs.
Hi Eric,
Thanks for writing this up. However, I’d like to hear a balanced discussion. It’s a bit of a bugbear of mine when people present solutions to specific problems as hard and fast general purpose rules that will apply to every situation and every team and every project. You can easily find articles from other people giving good reasons why pair programming hasn’t worked for them. In my experience, software development is complex and varies hugely from team to team, company to company.
I have worked in places where pair programming was great. I’ve also worked in places that pair programming was awful, and caused arguments, wasted time, frustration in teams… etc. Similarly I’ve worked in places where online code review was great and ended up with senior devs teaching very valuable lessons to juniors which simply wouldnt be possible doing pairing. I’ve also seen code reviews kick off with everyone getting angry and causing lots of friction.
What is important, is: When is pair programming useful? What sorts of teams, projects and environments can be improved with pair programming, and more importantly, when is pair programming NOT useful? What sort of training do people need in order to get the most out of pair programming?
I know us programmers like to have binary answers and rules that you simply follow to success, but unfortunately software development across companies is extremely diverse and I don’t think it helps the community to pigeonhole things like this.
In my opinion, pair programming is a tool, one of many tools that you should have in your toolbox, and you should use the right tool for the job. Identifying the differences between tools and which situation should be mapped to which tool is much more valuable than using a hammer for everything (and telling everyone they should use a hammer for everything).
Getting back to this after a really long wait…
That is a fair comment, and something that I will think about covering in the future. My short answer is that, like pretty much any engineering technique, you can introduce pairing poorly and have an environment where the incentives don’t make it work well.
I’m going to paraphrase Arlo Belshee a bit, and simply say that the reason I am for pairing is that it works better than any other approach I’ve come across.
It will be better if you have also some formula for those benefits …