Pair Programming 👯♀️
The secret skill of high-performing engineering teams
There are well-known engineering practices everyone respects, and then there are secrets.
Things that radically change the way you work, provide strong benefits to your team, yet few companies adopt.
Secrets are often hidden in plain sight. They just look unappealing and uncomfortable until you discover their power.
One of such secrets was remote work. For more than a decade, remote engineering has been a prerogative of open source communities and a handful of visionary companies. Then, the pandemic brought it front and center and shifted the conversation completely.
I argue there is another massive secret in engineering today, and that is pair programming.
Pair programming is the practice of making two people work on the same code, at the same time. If they work in an office, they literally sit side by side. If they work from home, they share their screen and do it remotely.
Pair programming, just like remote work, is counterintuitive. Even more so, it looks bad to all stakeholders:
💼 To managers, it feels like a waste — it's two devs working on the same code, when they could be doing two separate things.
🔨 To developers, it feels uncomfortable — social interaction is draining. And what about the sacred state of flow?
Nevertheless, there exist very successful companies who pair regularly, or most of the time, or even all the time. In some cases, they have been doing so for decades, and they loudly advocate the case for it.
This article is my best attempt to demystify this practice and tell you everything you should know about it:
👁️ Why you should pair program — a wide range of benefits that include code quality, productivity, and overall team happiness.
📖 How to pair program — a detailed process to do it right, standing on the shoulders of teams who have been doing it for decades.
⚖️ When you should pair program — let's see if these benefits apply to all kinds of tasks and situations.
🗺️ How to plan for it — how pairing changes management and general planning, how to get stakeholders' buy-in, and everything that's beyond programming itself.
💻 Remote pair programming — pairing is especially effective with remote work. Let's find out why and what are the best tools to support it.
📚 More articles to deep dive — case studies, tutorials and scientific research from an all-star cast that includes Alistair Cockburn, Laurie Williams, Martin Fowler, Eduardo Ferro, and more.
Let's dive in 👇
👁️ Why you should pair program
Pair programming is consistently adopted by some of the most well-known engineering teams in the world. The degree of adoption varies — here are some examples:
Pair most of the time → Thoughtworks
Pair all the time → Pivotal
Such companies report strong benefits that can be organized in five main categories:
📖 Knowledge Sharing
💬 Manager Behaviour
Some of these are to be expected, while others are wildly counterintuitive.
Let's see them one by one 👇
How could it be productive to assign two developers to the same task? It turns out it is, for three reasons:
Less Distractions — two people are less likely to get distracted and lose focus than one. That short trip to facebook doesn't look all that appealing when there is someone else looking at your screen.
More Awareness — when working for several hours on some problem, you might dig yourself into a rabbit hole and lose the correct perspective of the main task. This is also called yak shaving. Remember that time you spent all the afternoon on a bug and then fixed it in 10 minutes the morning after? This wouldn't probably happen in a team of two.
No Code Reviews — this is one of the factors I like the most: all the code is automatically reviewed. No further PRs to interrupt your productivity. Also, chances are this kind of review is way better than your usual PR.
Based on these elements, in their paper "The Costs and Benefits of Pair Programming", Cockburn and Williams showed how the immediate, raw output of a programming pair is only 15% smaller than that of two independent developers.
This 15% is easily repaid down the line by the improved code quality, automatic knowledge sharing, less turnover, and team growth (more on that later).
Pair programming consistently leads to higher code quality. Two people bring better problem solving, that turns into a better design overall.
Part of this is because of the double contribution, and part is because two people are more likely to keep their focus and a balanced perspective. As a solo developer, after some time on a task you may develop tunnel vision and fixate on implementation details that are not relevant to the bigger picture. Two people, instead, always keep each other in check.
📖 Knowledge Sharing
Pair programming is a phenomenal knowledge sharing device. There are at least three use cases where such sharing is valuable:
Ownership — code written this way has two owners out of the box. This makes your team more cohesive, resilient to turnover, and flexible in work allocation. It is also hard to replicate in any other way.
Onboarding — pair programming makes onboarding faster. It makes new hires get in touch with your practices, your culture, and it also helps them develop early relationships with peers.
Learning — you may pair people with different skill levels to accelerate the learning process of younger members.
One of the most common objections to pair programming is that it is draining due to the continuous social interaction. It is also believed that, being many developers introverted, they would come to despise this interaction.
As an introvert myself I can certainly relate, but I also feel this is not 100% correct. While it is true that introverts don't like much interaction, they do crave intimate interactions with those who are close to their interests.
Pair programming allows to develop deep relationships without being socially overwhelming, which is the best possible scenario for an introvert.
There is no deny that working with a peer is more intense than working by yourself — but not in a way that jeopardises the whole practice.
Cockburn and Williams notice in their study:
In statistically significant results, pair programming teams who had earlier programmed alone reported that they enjoyed pair programming more and that they were more confident in their programs than when they programmed alone.
But how much more? In a survey among the same participants, a stunning 80%+ of developers reported they enjoy working more because of pair programming.
Participants report a new sense of confidence and shared ownership, that ultimately makes them happier. Quotes from actual developers 👇
I find it reassuring to know that my partner is constantly reviewing my code while I drive.
It’s nice to celebrate with somebody when something works.
💬 Manager Behaviour
Pair programming emphasises communication, giving and receiving constructive feedback, and working together towards a goal.
These skills are crucial in all other kinds of situations, from managing people, to mentoring, to negotiating with stakeholders.
Engineers who pair regularly experience a professional growth that goes beyond coding.
⚖️ When you should pair program
Pair programming is best when it allows you to produce high quality software and share knowledge in the process. For this reason, as Kent Beck says:
Pairing works when there is sufficient uncertainty in the problem be solved and the approach to solving it.
Viceversa, pairing doesn't bring much value for mechanical or trivial tasks that both members could accomplish by themselves.
If the work doesn't require taking any decisions, and there is no learning involved, you might as well avoid pairing.
📖 How to pair program
Pair programming is different than regular programming in many decisive ways. This is a short guide on how to do it right.
Driver vs Navigator
At any given time, when you pair there is one person who writes code, and one that observes. They are respectively called Driver and Navigator.
Aside from who actually writes the code, their main roles are:
The Driver keeps the focus on the current step.
The Navigator keeps the focus on the final goal.
As a Driver, you are focused on the task at hand — what to do and how. To help communication, you should learn to think out loud. Talk about what you are doing, what you are going to do and how.
As a Navigator, you always walk on a fine line where you should 1) provide valuable input, but 2) avoid to interrupt the driver's flow. Skilled navigators understand when their partner is ready to listen, and when they are not.
Navigators do three main things:
🧠 Brainstorm — they discuss design choices and suggest the way forward.
📖 Guide — they make sure the task relates to the final goal.
🔍 Review — they spot errors and propose improvements. Just like a regular code review, but in real time.
This is how you can run a good pairing session:
Set a clear objective — define the goal of the session. This is crucial as you and your partner will keep each other accountable.
Set a time — how much should the session last? Schedule it in advance to frame it within the rest of each other's work.
Work in iterations — to stay effective, you will need rest. Most teams who pair regularly use the pomodoro technique or equivalent short iterations, followed by periods of rest.
Swap driver / navigator — swap your roles frequently, for example at the end of each iteration. This helps to keep focus and stay productive.
"There's a joke that pairs, like fish and house guests, go rotten after three days" — Zach Brock, Engineering Manager at Square.
The most common pairing setup is between peers. If the driver and navigator have different skill levels, instead, be aware you are working in one of two modes:
Driver receives knowledge — you trade productivity in favour of knowledge transmission.
Driver has the most knowledge/practice — you trade knowledge transmission in favour of productivity. This is an opportunity for novices to see more experience fellows “in action”.
Having different skill levels doesn't mean one acts as a supervisor for the other. Whenever you pair, you act as peers, even if your respective contribution is not the same. This is crucial to make pairing works, and it is the reason why it is hard to pair with your actual supervisor.
🗺️ How to plan for pair programming
From a management perspective, pair programming is not a transparent practice — you should actively plan for it.
Here is some advice on how to get started:
Get buy-in from management — elaborate on the benefits of pairing, and propose an experiment with limited scope. In my experience, building small success stories is the best way to propagate a practice over time.
Assign couples of developers to tasks — pair programming implies shared ownership. Decide the couples from the very beginning to facilitate coordination.
Mix up people — if possible, mix up couples over time. When partners get comfortable with each other they will resist the change. Mixing is healthy as it allows to share more knowledge and keep productivity high.
Don't give up — pairing is a skill that needs to be trained. At the beginning, it will feel uncomfortable. Get constant feedback and iterate over it for at least a couple of months, before drawing some conclusions.
💻 Remote pair programming
Many companies are reluctant to adopt pair programming because they believe it doesn't fit well with remote. Here are two typical arguments about it:
Async work — “remote is about async, so any practice that requires people to work at exactly the same time is bound to be inefficient”.
Physical interaction — “pair programming only works if you are sitting side by side. Otherwise it's just a long, uncomfortable call”.
Let's debunk both, starting by noting that some of the biggest proponents of pairing, like Thoughtworks, GitLab, and Github, are remote-first companies.
In a remote environment, pair programming is one of the best things you can use for two programmers!” — Jason Warner, former CTO @ GitHub
This is not casual. Counterintuitively, pair programming makes remote work better in many meaningful ways.
A major fallacy about async work is that it implies you should never have meetings or sync collaboration. But these are still valuable. It just means you should be mindful of when using one mode or the other.
Pair programming, in particular, enforces accountability and helps you not to get stuck when you face a challenge.
Ronald from GitLab says 👇
Working in isolation, without the distractions of the office, is great when you're in the zone. "It works until you run into a difficult problem to solve," says Ronald. "Spending three days on a problem, before getting to the single line of code that solves it, sucks." If you find yourself not making any progress on a challenge, it's probably time to pair.
If the major drawback of remote work is the lack of human connection, pairing makes for a chance to get closer to each other. There aren’t many ways to build meaningful work relationships from remote — pairing is one of these.
Also, pair programming tools are now leaps and bounds better than what they used to be. This can make remote pairing even more effective than pairing on site, because it is easier to avoid distractions with headphones on.
Let’s look at tools, then👇
🔨 Tools for Pair Programming
The best tools to pair today do much more than sharing your screen. They usually include the following features:
Multi-user editing — all participants can control the editor (or any app) with their mouse and keyboard.
Simultaneous screen sharing — all participants can share their screen simultaneously.
Strong video & audio experience — high quality and low latency.
Drawing / highlighting — being able to draw something on the screen is incredibly useful to highlight sections and explain ideas.
There are a few great tools that have been designed for this specific purpose. These are the best four I know of:
There are also tools that allow collaborative editing in your IDE. They give you more autonomy, as you have the ability to personalise your environment, check other parts of the codebase without interrupting your partner, and temporarily work in parallel.
Two of the most popular are:
Live Share for VS Code
Floobits for IntelliJ, Emacs, Vim, and more
With respect to the other tools above, though, you lose other collaboration features. Also, keep in mind pair programming is not really about working in parallel.
Finally, here are the most insightful readings I have found about the topic.
📑 On Pair Programming — this article from Thoughtworks is a comprehensive guide on pair programming that covers the benefits, challenges, and everything you need to know.
📑 The Costs and Benefits of Pair Programming — a peer-reviewed paper by Cockburn and Williams about the outstanding impact of pair programming on engineering teams. A must read.
📑 Why Every Startup Should Pair Program — Pivotal team pairs literally all the time. They built an entire culture around it and explained it in this great article.
📑 Code Reviews (Synchronous and Asynchronous) — Eduardo Ferro explains the impact of pair programming on code reviews. A very insightful read about one of the most important benefits of pairing.
⭐ Weekly Featured Jobs
Here are the remote engineering jobs I recommend this week.
I personally review all of them and have a chat with each company to get more context and better understand the opportunity.
The.com is building the reusable web, making it simple to create, remix, and launch websites. It's and incredible tool that changes how people think about authorship online.
You can find more jobs, or submit your own here.
I think that there are other additional benefits:
- It decreases the bus factor for any part of the codebase (and facilitates shared ownership at the team level). When someone leaves, it is not dramatic.
- It is easy to scale the team at any time. You can absorb two new developers and generate two pairs for each pair.