5 years of Pair Programming

Steve Hiehn
7 min readFeb 19, 2019

--

I recently moved from Toronto to Vancouver to start a fresh new chapter as a software engineer at a Canadian startup called CTO.ai. When I left Toronto I left a good job at Pivotal. Pivotal is a company that practices pair programming (pairing) full-time at scale. This will be my first time working a solo programming gig after 5yrs of pairing. Though, I am excited to once again solo, I have concerns about working at company that doesn’t pair. I don’t think its works in every situation but I have witnessed first hand some incredible advantages, like code quality and knowledge share. I ended up working in a pairing environment in the first place not because I sought it out or even knew much about it, but had just happened to have connections at a shop that practiced it. When I started job hunting in Vancouver, I started to realize just how rare it actually is for a company to do pair programming at that scale. When I would tell potential employers about my work experience, they seemed curious but discussed it like a strange social experiment rather than something a company would actually want to do. Since realizing that this was more of a rare experience, I wanted to bring some closure to that chapter of my life/career by sharing a few thoughts and reflections of the experience while they are still fresh in my mind.

So, pair programming: is it a good thing? Well, let’s start with why companies might decide to pair in the first place. At its core the idea is that a pair is greater than the sum of its parts. When people pair they spot each others errors, discuss architecture, and share knowledge. At least, this is the hope. Let me just list some pros/cons I’ve noticed:

Pros:

  • Knowledge share is unparalleled. Traditional dev shops often have to invest time dedicated to developer ramp-up. In a pairing environment when someone new joins a team they start learning the code base simply by pairing with the rest of the team (that presumably already knows the code base)
  • It makes people are replaceable. This is a big value add IMHO. It may sound cold at first thought but it’s a good thing. People join other teams and leave companies for an endless list of reasons. That’s just the way it is. So, by having the knowledge spread across a team it’s unlikely that the sky will fall if someone does move on.
  • Reduces developer hierarchy. Although people may have different titles and salaries in a pairing environment the developers are touching more of the same codebase. This is a good thing both for the health of the team and the personal growth of the developers. Traditional dev shops tends to have huge divides between junior and senior developers. Juniors who are often interested in growing but are not empowered because seniors and management do not trust them enough to work unsupervised on critical parts of the system

Cons:

  • At face value its is twice as expensive. On short term execution, contracts with limited funds having individuals working in parallel but on different features is probably a safer bet. However, in the long term that may not be the case. It is difficult to quantify this but if you work quickly and make poor engineering decisions in the long term it may end up costing the company more dollars to deal with bugs fixes and maintenance associated with a poor code base.
  • Half the throughput. This is similar to the last point but in terms of timelines. Two devs could in theory be working on two separate features potentially increasing the overall velocity.

The truth is, after pairing for 5yrs I’m just not completely convinced its always a good idea despite the pros. I actually prefer not doing it on a full-time basis because its not always effective. In order to determine when it might be effective or not we need to define a few of the key factors. Of course, there are many factors that could play into a situation where pairing may or may not work I will list the ones I believe are most important. The factors I see most likely to determine whether pairing will be effective are: skill level of the developers, type of work (Execution or Research) and then the personality of the developers. I organized some of the factors into a simple matrix so we can talk through noteworthy combinations.

Most of the work that was done at my previous company could either be classified as execution or R&D (research and development). Execution was work that had clear requirements, needed to be built, and the developers had first hand experience building something similar in the past. R&D was product work that had goals, no clear requirements and the developers could not directly rely on their prior domain experience.

The type of work matters. As you can see from the graphic I think pairing is much better suited for execution work than R&D. I think the reason for this is because most people approach research in very different ways. Someone might want to query google desperate for an information foothold while others might just dive straight into tech docs. The point is people need to be free to fill in their own knowledge gaps at their own rate. Let’s be honest, co-ordinating reading speeds of dry tech documents in a shared internet browser for extended periods of time is nothing short of torture.

On the other hand, execution work is where pairing really shines. It is almost always effective for a number of reasons. Developers naturally call each other out on best practices. For example, when deadlines approach and no one is watching, it can be very tempting to try and get away with not writing as many tests. Another thing that pair does is spread the knowledge of the code base around the team. Within only a few days at my new company I could see extreme knowledge silos. People who are clearly the pillars that the entire project depends on. The problem is, if one of those people leave with all the knowledge of the system, the rest of the team ends up in a very bad position. My experience with pairing is that more people are exposed to more parts of the system, meaning work will continue even when key players are not present.

Next, I want to look at the combinations of developer skill levels, because this also plays into pairing being effective or not. From my experience, two strong developers pairing for extended lengths of time is more a waste of resources that anything. There is a risk that they spend too much time debating equally viable approaches when there isn’t a clear authority. I also find its more likely that one will feel bored and pay less attention when someone else is confidently executing without needing assistance.

The combination of junior and senior almost always good. The juniors growth will be super charged. The seniors also benefit by not having to explicitly invest time in communicating team standards and code quality expectations. This is often the case because the dialogue happens constantly throughout the pairing experience.

The personality of the developers also plays into this in a big way. Of course, personalities are much more nuanced than simply passive and dominant but for the sake of limiting the scope, let’s force these binaries. Similar to the senior/junior combinations, two dominate personalities can often lead to more conflict than benefit. This is essentially the too many chefs, not enough cooks problem. For example multiple equally valid design patterns could be used to build a feature and instead of moving forward on one the dev spend time making a case for their arbitrary preference.

So far in this post I’ve been mostly focusing on the objective cost/benefit of pairing from a companies perspective but there is another important conversation around the happiness and productivity of the individual. Pairing is very exhausting. Both emotionally and cognitively. Much more so than soloing. Interestingly enough, I find the person not doing the driving has to focus harder. When you are typing you have no choice but to be present but when you are following someone else’s train of thought you have no choice but to be attentive on their schedule and prevent your mind from wandering.

Another complication with pairing is the social overhead. You have to work uncomfortably close to people and depending on the person this can be overwhelming. I would regularly go home from work and lay on the couch just reviewing the subtle social interactions over and over and wonder if I accurately represented myself. I know this could be the case in many jobs but I would rather focus my limited energy on writing high quality code rather than co-ordinating a keyboard with someone who didn’t get enough sleep the night before.

And the last point I will make is code ownership. This is a double edged sword. A smart tech lead I worked with would often say “cattle not pets people, cattle not pets!”. He was essentially reminding us to focus on the big picture and not obsess with details and ownership. You want people to take ownership but not become a protectionist. I find when people soloing they feel more ownership of the code they write but this can actually become a problem if they are too defensive when people alter or criticize it.

SUMMARY :

In summary, I think pairing is best for execution work with a team of mixed skill levels. It’s simply not for everyone nor is it good for every situation. If a company decides to enforce pairing I think its best to explicitly hire for it in the first place.

I’m excited about my new job and looking forward to soloing once again. I have a feeling I will end up missing certain aspects of pairing like knowledge share & code consistency. If my new team asked me if I would I recommend pairing I would say only when it makes sense. I would say let’s pair when a new person joins the team or we have to build critical design features that will deeply affect the product architecture for a long time to come.

--

--