Skip to main content
Test Double company logo
Services
Services Overview
Holistic software investment consulting
Software Delivery
Accelerate quality software development
Product Management
Launch modern product orgs
Legacy Modernization
Renovate legacy software systems
DevOps
Scale infrastructure smoothly
Upgrade Rails
Update Rails versions seamlessly
Technical Recruitment
Build tech & product teams
Technical Assessments
Uncover root causes & improvements
Case Studies
Solutions
Accelerate Quality Software
Software Delivery, DevOps, & Product Delivery
Maximize Software Investments
Product Performance, Product Scaling, & Technical Assessments
Future-Proof Innovative Software
Legacy Modernization, Product Transformation, Upgrade Rails, Technical Recruitment
About
About
What's a test double?
Approach
Meeting you where you are
Founder's Story
The origin of our mission
Culture
Culture & Careers
Double Agents decoded
Great Causes
Great code for great causes
EDI
Equity, diversity & inclusion
Insights
All Insights
Hot takes and tips for all things software
Leadership
Bold opinions and insights for tech leaders
Developer
Essential coding tutorials and tools
Product Manager
Practical advice for real-world challenges
Say Hello
Test Double logo
Menu
Services
BackGrid of dots icon
Services Overview
Holistic software investment consulting
Software Delivery
Accelerate quality software development
Product Management
Launch modern product orgs
Legacy Modernization
Renovate legacy software systems
Cycle icon
DevOps
Scale infrastructure smoothly
Upgrade Rails
Update Rails versions seamlessly
Technical Recruitment
Build tech & product teams
Technical Assessments
Uncover root causes & improvements
Case Studies
Solutions
Solutions
Accelerate Quality Software
Software Delivery, DevOps, & Product Delivery
Maximize Software Investments
Product Performance, Product Scaling, & Technical Assessments
Future-Proof Innovative Software
Legacy Modernization, Product Transformation, Upgrade Rails, Technical Recruitment
About
About
About
What's a test double?
Approach
Meeting you where you are
Founder's Story
The origin of our mission
Culture
Culture
Culture & Careers
Double Agents decoded
Great Causes
Great code for great causes
EDI
Equity, diversity & inclusion
Insights
Insights
All Insights
Hot takes and tips for all things software
Leadership
Bold opinions and insights for tech leaders
Developer
Essential coding tutorials and tools
Product Manager
Practical advice for real-world challenges
Say hello
Developers
Developers
Developers
Communication & teams

Pair programming: the unexpected benefits and challenges

Discover the pros and cons of pair programming, and learn how it can improve code quality, team collaboration, and developer growth.
Eve Ragins
|
December 6, 2022
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

For the vast majority of my career, I rarely pair-programmed. I’d even tried it a couple of times, but it was awkward and clunky and slow. I wasn’t sold. It became something I only did if I or somebody else was really (really) stuck on something, but never in the regular course of things.

Then I worked with a client who practiced extreme programming and paired by default. That is, the expectation was that you didn’t work on code by yourself. Instead, you spent your day pairing with a partner. What this looked like was this:

  1. Every day at our morning huddle, everybody on the team got a buddy for the day based on:  
       
    • What was in-progress or to-be-started
    •  
    • Who was holding context
    •  
    • Who needed context
    •  
    • Who hadn’t paired together recently
    •  
    • How people’s schedules aligned
    •  
  2. For the rest of the day, we worked virtually side-by-side. We didn’t have virtual camera portals, but we did communicate our schedules on slack and almost immediately hop into a call using software designed for pairing, such as Pop or Tuple.
  3. We worked on whatever we would’ve done solo, taking time for breaks and lunch. This ranged from obvious coding tasks to configuring our monitoring tools, doing pre-deployment testing, deploying, reaching out to other teams with questions, and even attending each others’ non-personal meetings.
  4. Sometimes we’d even pull in another pair for more input or eyes on something.
  5. If we were an odd number, somebody would “solo” for that day, reaching out if we wanted another’s input.

Here is what I learned.

Pros of pair programming

Shared code ownership

This was the first project I’ve been on where there simply wasn’t the same sense of individualized code or feature ownership I’ve seen and been a part of on other teams. Rather than everybody having their own section of the playground over which they ruled, it was one big playground and everybody took responsibility.

Humility

Asking for input on something became a cultural norm, and people’s egos were rarely in the picture.

In consequence, people felt safe, discussion came easily, and everybody was generally pleasant to be around.

Onboarding

Pairing all the time allowed people to be brought into the fold on day one and be relatively comfortable with the codebase by the time they had access, which for this client took at least a couple of weeks.

It helped to naturally share and normalize team practices, such as how we used git, without almost no friction and no real need for a “here’s how we … " document or retroactively correcting somebody.

Shared context

The constant pairing and daily pair rotations made it so that everybody had at least moderate context on many parts of the codebase, features, and project as a whole.

Everybody could contribute valuably to team discussions.

Team durability

The prospect of losing any one person was not that big of a deal, which isn’t to say that they wouldn’t be missed.

Indeed, even when my team loaned one of our stronger members to a different team, work went on with minimal disruption. This held true as others left, and I imagine it held true when I rolled off the project.

Growth

Working with others, even on mundane pieces of code, really helped reinforce or teach best practices, mentor on concepts, and set a platform for healthy discussion that isn’t focused on “my way” or “your way.”

This growth extended far beyond code construction into areas such as how to break down problems, ask good questions, write documentation, etc.

And as a more senior person on an unfamiliar code base, tech stack, and domain, my growth opportunities were plenty, too, in both hard and soft skills.

Committing to main

We almost always committed directly to main because the code was being reviewed as it was written — all the “before code gets merged …” process I’ve seen on other teams was simply a non-issue.

By contrast, I’ve been on projects where “before code gets merged” was all some people talked about, even having team members devoted to the effort.

Mutual accountability

The overall code quality was better due to mutual accountability and raising the standard to the combined set of things people care about.

Working individually, it’s easy to just kind of be like, “eh, I know I should, but I don’t feel like doing …”; but with a pair, even if you both don’t feel like doing it, you’re more likely to do it if it’s the right thing. Or, as the case may be, you both may decide that it’s not that important in this scenario.

Focus

It was less likely that somebody would go down a rabbit hole or get stuck on something that could be easily resolved by asking somebody else.

Connectedness

I was able to feel more connected to my coworkers than I would have if my only other interaction with them was in meetings. This is something that I tend to undervalue, but it can be the difference between feeling isolated or not.

Cons of pair programming

While some of the cons may be universal, many of them are how I personally responded and may not apply to others. Additionally, some of them might be a side-effect of the particular codebase I was working on combined with the team cycling.

A quick aside to talk about the team cycling: Above I said that Team Durability was a bonus, and it is; but over the course of four months, not counting myself, my team added three people and lost three people on a team averaging around 6 developers. Pairing-by-default helped us weather it far better than if we were working individually, but that much churn still meant that we never really coalesced around a sense of style as people rolled on and off. I call it out since it impacts the below.

Shifting visions

Because there was no clear feature owner, sometimes the “vision/master plan/essence” for an approach got lost as it shuffled between people (a la the telephone game).

Similarly — at least on our codebase — we never ended up with a consistent pattern to follow of “here’s how we implement xyz.” I think as each pair reviewed a problem, they’d add their own combined flavor to it.

I suspect this says more about the state of the codebase and ancillary practices than it does about pairing since pairing should really result in the opposite.

Surprises

Related to the above, as a feature made its way around the team, it was sometimes jarring to see code re-done several times as people applied their own sense of style and different people weighed in on different aspects of the solution.

Pro, though, it was extremely rare that a pair broke something that previously worked.

Work-life balance

It was hard to balance my work and personal life, especially being in a different timezone from the rest of my team.

Scheduling

Having a pre-set schedule was very hard on me – being able to keep a flexible schedule and work outside of the standard working hours is one of the top things I look for in a job.

It’s exhausting

Pairing with somebody else requires a heightened sense of awareness and engagement that takes a lot of energy. For me, very much an introvert, I ended up so drained that I had nothing left for day-to-day tasks of living, like staying on top of dishes, putting clothes away, or cooking for myself. I ended up renegotiating my working agreement with the team to pair only half a day, which worked a lot better for me, but also made it kind of awkward.

Personal satisfaction

I never really got “into the zone” when pairing, and the zen-like state of just me and the code never happened, which in turn meant that my overall satisfaction was lower.

I also had a hard time doing my own research. For example, I was weeks into the project before I found the time and energy to read up on and explore language features I wasn’t familiar with. Sure, I could have done this with a pair, but I really just wanted a couple of hours to commune with the documentation and spin up a sandbox.

Also, I tend to do my best thinking when I’m not trying to talk at the same time.

Auditory concerns

It was hard to work out and about due to external noise or due to being the one making noise.

I canceled my spot at a co-working space since I didn’t want to be the person talking all day.

I couldn’t listen to music at the same time as pairing. It’s not something I do much, but it’s nice on occasion. Maybe other people did with headphones, but I’m a no-headphone-if-I-can-avoid-it kind of person.

Nonsensical pairing

Some things don’t make a lot of sense to pair on, like reading documentation. My team never figured out that balance.

Unrealistic expectations

Because of the “thou shalt pair all day” mindset, people struggled.

Of the three people who cycled off my team, two of them quit citing the pairing expectation as part of the reason.

I heard rumor that others schedule meetings with themselves to avoid pairing.

Needless to say, both are signs that the expectations went too far.

Cost

In discussions around pair programming, especially pairing all the time, one of the things that often comes up is cost.

Do I think everything ended up costing twice as much? No. Not at all.

In my own speculation, due to the shared context, accelerated individual growth, and collective ownership (i.e., protection against team changes), I was estimating that everything may have cost like 1.2 - 1.5x as expensive, maybe less.

This study indicates that I wasn’t generous enough. They conclude: “The development cost for these benefits is not the 100% that might be expected, but is approximately 15%. This is repaid in shorter and less expensive testing, quality assurance, and field support.”

As it doesn’t seem like they factor in team durability, it’s possible that the long-term cost of pairing is actually less than the cost to pay a single person when executed optimally.

Closing thoughts on pair programming

If you have the opportunity to give pairing-by-default a try, I highly recommend going for it. With this experience, I’m far, far more likely to jump into a call for something mundane “just because.” And that “just because” might even be because I’m feeling more social and have nothing to do with code.

Embrace the awkwardness.

I suspect that, as with most things, a healthy balance to pairing is the best solution.

For more on pairing, check out our pairing ethos at Test Double, which goes over how to be a good pair. 💃🕺

Related Insights

🔗
How to run effective retrospectives for agile teams
🔗
How effective pull request reviews transform your team

Explore our insights

See all insights
Leadership
Leadership
Leadership
The business of AI: Solve real problems for real people

After participating in the Perplexity AI Business Fellowship, one thing became clear: the AI hype cycle is missing the business fundamentals. Here are 3 evidence-based insights from practitioners actually building or investing in AI solutions that solve real problems.

by
Cathy Colliver
Leadership
Leadership
Leadership
Pragmatic approaches to agentic coding for engineering leaders

Discover essential practices for AI agentic coding to enhance your team’s AI development learning and adoption, while avoiding common pitfalls of vibe coding.

by
A.J. Hekman
by
Aaron Gough
by
Alex Martin
by
Dave Mosher
by
David Lewis
Developers
Developers
Developers
16 things software developers believe, per a Justin Searls survey

Ruby on Rails developer Justin Searls made a personality quiz, and more than 7,000 software developers filled it out. Here's what it revealed.

by
Justin Searls
Letter art spelling out NEAT

Join the conversation

Technology is a means to an end: answers to very human questions. That’s why we created a community for developers and product managers.

Explore the community
Test Double Executive Leadership Team

Learn about our team

Like what we have to say about building great software and great teams?

Get to know us
Test Double company logo
Improving the way the world builds software.
What we do
Services OverviewSoftware DeliveryProduct ManagementLegacy ModernizationDevOpsUpgrade RailsTechnical RecruitmentTechnical Assessments
Who WE ARE
About UsCulture & CareersGreat CausesEDIOur TeamContact UsNews & AwardsN.E.A.T.
Resources
Case StudiesAll InsightsLeadership InsightsDeveloper InsightsProduct InsightsPairing & Office Hours
NEWSLETTER
Sign up hear about our latest innovations.
Your email has been added!
Oops! Something went wrong while submitting the form.
Standard Ruby badge
614.349.4279hello@testdouble.com
Privacy Policy
© 2020 Test Double. All Rights Reserved.