I have worked at two software companies (Qumulo & StrongDM) that almost exclusively default to Pair programming. Pair programming is a technique whereby two programmers work collaboratively, oftentimes on the sharing the same screen, on a piece of code. There are typically two roles in pair programming: the “driver”, who has control of the mouse and the keyboard and the “navigator”, who observes the work of the driver, offers suggestions and corrections to both algorithm and code. Alternatively, in a remote world, the driver is the one sharing her screen on a Zoom session. There are numerous reasons why software organizations adopt pair programming, one of which is the belief that it results in higher quality software. I’ll get into the other reasons in a bit. Over the years, I’ve often been challenged about the merits of pair programming. The first challenge is on the notion that pair programming yields better quality software. The second is on productivity. Surely having two people work on a piece of code together cuts the overall team productivity by half.
Before diving into these two areas, I’d like to first start with why do pair programming at all. I mean it does sound counter-intuitive, so why did these engineering teams adopt this technique? There are numerous intuitive reasons for why pair programming can be a good technique to use. These are collaboration, onboarding & risk management. I’ll get into the quality and productivity reasons later on, and I will complement my arguments with data.
I’ll start with the onboarding and risk management reasons, those are easier to reason about. It makes intuitive sense that working with a peer on some portion of the codebase helps a new software engineer quickly ramp up. Rather than try and figure out the codebase alone, a new hire will have a pair that she can work with from day 1. In my experience it hasn’t been unusual for new hires to commit code on their very first day on the job. New hires are always paired up with a more tenured engineer. This is done deliberately to help accelerate the onboarding and learning process. The experienced engineer can help the new hire navigate the codebase, get her up to speed on engineering practices like testing, CI/CD and so on. Additionally, knowing that you are paired up with someone who knows the codebase better than you, offers a margin of safety. As a new hire, I can start trying to directly contribute to the codebase knowing that my pair will help if I am stuck or headed in the wrong direction.
One other subtle, yet important benefit of pair programming is risk management. Pair programming reduces the risk of having a 1:1 mapping between a developer and a particular piece of code. You should no longer have a portion of your codebase that is owned or understood by only 1 developer. Even if you do, which you will, the surface area of that code relative to your entire codebase should be fairly small. Because there are almost always two developers working together on the codebase, it therefore implies that there should be at least 2 developers who can understand a particular piece of code. This reduces being entirely dependent on a single developer who understands a portion of your codebase. Another side-benefit of pairing is that it allows developers to expand their scope. It is not unusual for two pairs to trade partners. This allows two of the four developers (for every trade) to work on a new codebase, which is healthy for morale, skills and personal development. It also reduces the risk of being dependent on one or a few developers who understand a particular piece of code. Additionally, having a new pair of eyes on the codebase, helps keep it readable, well factored and tested.
“It is psychologically soothing to be sure that that no major mistakes had been made . . . I find it reassuring to know that [partner] is constantly reviewing my code while I drive. I can be sure I had done a good job if someone else I trust had been watching and approved.” Source: The costs and benefits of pair programming
The collaboration argument should also be easy to infer, or is it?. Two people working together, asynchronously or synchronously, is by definition a collaborative experience. That seems like a tautology though and a rather weak argument. There are numerous examples of having two or more people working together can result in a non-collaborative, even combative, environment. Can we do better than this? This is where studies conducted in academia on computer science students comes in handy. Consider the below. Bold emphasis mine.
The benefits of this technique over individual programming were initially demonstrated by Williams and Upchurch (2001), who observed that students working in pairs found the experience more enjoyable than working alone and repeatedly cited how much they had learned from each other. Team communication and effectiveness also improved. Students enjoyed the camaraderie, and felt more confident. Nagappan et al. (2003) found that students and demonstrators reported labs to be more productive, less frustrating and more conducive to advanced, active learning than traditional labs. McDowell, Werner, Bullock and Fernald (2006) found that paired students were significantly more likely to remain in the course through to the final exam (90.8% versus 80.4%). Paired students were also 18% more likely to attempt the subsequent course in programming were also more likely to register for a computer science major. Building on this work, a systematic review by Salleh et al. (2011) concluded that pair programming consistently leads to improved grades and increased student satisfaction. Source: Evaluating Effectiveness of Pair Programming as a Teaching Tool in Programming Courses
The arguments for the impact of pair programming to both productivity and code quality is best assessed from a very interesting experiment conducted at the University of Utah in 1999. The experiment, undertaken in an advanced undergraduate software engineering course divided the students into two groups. One third of the students conducted class projects as they typically did; alone. The other two-thirds were paired up and instructed to complete the projects as a pair. The class instructor was then able to measure the performance of both groups over time, specifically over 3 projects throughout the course. Performance was evaluated on both the time to complete each project and the quality of the submitted project.
The graph below shows the productivity, measured in time to complete each project, for both groups. The students that worked alone were faster (~15%)to complete each assignment than the pair, but not by a whole lot. They were most definitely not twice as fast as a pair. Also note, that the productivity of the pair improved over time presumably due to the time it takes for two people to work together.
The next chart looks at the quality of the submitted projects, again by comparing the solo students to those working in pairs. The quality, as measured by % of test cases passed, of the projects submitted by the pair were consistently higher quality (~15%) than the individual students.
In fairness, it isn’t easy to fully embrace pair programming. The main challenges I have observed are around team dynamics and hiring. The team dynamics is something that was briefly touched upon in the University of Utah study, whereby the productivity of a pair improved over time. That improvement isn’t guaranteed though and depends entirely on the ability of the pair to work well together, which sometimes won’t happen. As a result you might have to shuffle pairs around until you settle on a healthy working relationship across all pairs, if at all possible.
Pair programming can pose some hiring challenges, especially with more senior engineers who might be reluctant to work in a completely alien environment. It’s hard to suddenly make an abrupt change to how you work, especially if you’ve been doing it for 10+ years. I have found that one of the better ways to deal with this issue is to be very upfront about it with candidates. In my experience the vast majority of candidates will both understand it and embrace it, but it definitely will require you to be upfront about it in the interview process.
One might dismiss this data and make an argument that classroom performance isn’t really indicative of professional software development. There’s definitely an element of truth in this argument. However, I think that it’s almost impossible to conduct an experiment like the above in a professional software development setting. I doubt we would go as far as splitting our engineering teams into two cohorts and ask each to build the same features or products. So, we’re left with academic experiments run on computer science students.
And, my own totally subjective opinion on the matter: Pair programming results in healthier software development teams and produces higher quality code. Trust me :)