Pair Programming Practices
Two people working at one computer, on one task, at the same time. The most-debated practice in software engineering — variously promoted as the way to build the best teams and dismissed as half the productivity at the same cost. Both views miss what pairing actually does.
The honest assessment: pair programming is sometimes valuable, sometimes wasteful, depending on context. The question is not whether to pair always or never, but when. This page is about that.
What pairing actually does
Working as a pair changes the work in three ways:
1. **Two minds on one problem in real time.** Differing instincts, different blind spots; bugs and bad decisions get caught earlier.
2. **Continuous review.** No separate review phase; the review happens as code is written.
3. **Shared context.** Both engineers know the change, the reasoning, the alternatives considered.
What pairing does not do:
- It does not double output (or halve it; the relationship is more complex)
- It does not substitute for design thinking; bad decisions made together are still bad decisions
- It does not make weak engineers strong by osmosis
When pairing pays
Pairing produces real value in specific circumstances:
Hard problems
Problems where the right approach is not obvious. Two people can explore alternatives, catch mistakes earlier, and produce a better answer than one person working alone followed by code review.
Onboarding
Bringing a new team member up to speed on a complex codebase. The new person learns the conventions, tooling, mental model. The experienced person discovers gaps in their own understanding by being asked to explain.
Cross-pollination
When two engineers from different specialties work together, both learn. A backend engineer pairing on frontend work, or vice versa, gains real exposure faster than reading documentation.
Critical or sensitive code
Security-sensitive code, infrastructure changes with high blast radius, payment systems. The "two engineers signed off in real time" creates a record and reduces single-mistake risk.
Building team norms
Pairing is one of the most effective ways to establish shared conventions. New patterns get adopted faster when senior engineers regularly work alongside everyone.
When pairing does not pay
Pairing is wasteful in specific situations:
Routine work
Trivial bug fixes, simple feature additions, work that does not require deep thought. Two people on this is a literal waste; the work could be split into two parallel pieces.
Mismatched skill levels (sometimes)
A senior engineer pairing for hours on something a junior could do alone is bad pacing. The junior should do the work alone; the senior reviews. Pairing here would be expensive mentoring.
The exception: pairing across skill levels for *learning purposes* is genuinely valuable. The cost is real but the return is in the junior's growth. Frame it as mentoring, not as production work.
Bad cultural fit
Pairing requires real trust and willingness to think out loud. If the team culture punishes mistakes or the engineers are uncomfortable being seen "not knowing," pairing fails. The first investment is cultural; pairing as a forced practice on a team that doesn't trust each other is worse than not pairing.
Long sessions without breaks
Multi-hour pairing sessions exhaust both engineers. Productive pairing has built-in breaks; a "we'll pair all day" plan is usually unsustainable.
The styles of pairing
Driver/navigator
One person types ("driver"), the other thinks at a higher level ("navigator"). The navigator suggests direction; the driver translates to code. Roles switch periodically (typically every 15–30 minutes).
This is the classical model. It works for most pairing situations.
Ping-pong (especially with TDD)
One person writes a failing test; the other writes the code to make it pass; the first refactors; switch. Forces frequent role exchange and produces test-first code by structure.
Strong-style pairing
The driver does only what the navigator dictates. Forces verbal communication; particularly useful for onboarding (the new person drives, the experienced person navigates, every action goes through verbal description).
Useful in specific contexts; usually too rigid for ongoing work.
Mob programming
Three or more people on one task. The intensity multiplies. Generally only worth it for genuinely difficult or critical work.
Remote pairing
Remote pairing is structurally different from in-person:
- **Latency** matters; even small delays in audio break the rhythm
- **Screen sharing** has friction (which one is shared, how to switch)
- **Tools** matter; tools like Tuple, Code With Me, Live Share are designed for remote pairing
- **Async vs. sync** boundaries blur; remote pairs sometimes drift into "both working on the same thing in parallel" which is not pairing
Remote pairing works but takes more deliberate effort than in-person.
Specific patterns that work
Pre-pair planning
Before pairing, agree on:
- The specific outcome (a feature, a refactor, learning a system)
- The expected duration (1 hour, half a day, a full day)
- Who drives first
- When to switch
Skipping this leads to drift.
Regular breaks
Every 50 minutes is reasonable. The 50-10 cadence (50 work, 10 break) is sustainable; ad-hoc unstructured breaks aren't.
Stop when stuck
If pairing on a problem is not working, separate. Each person tries alone for a while. Reconvene when one or both has progress.
Take breaks for solo deep work
Pairing constantly produces shallower thinking than solo work in some areas. Don't pair on everything.
Common failure patterns
- **Pairing because "we should pair"** without specific reason. Often becomes parallel work pretending to be pairing.
- **Forced pairing as policy.** Pairing is most effective when chosen by the engineers; mandated pairing produces resistance.
- **Pairing on routine work.** Wasteful; better split.
- **Pairing without breaks.** Exhausts both engineers; quality drops.
- **One person dominating.** Pairing produces value through contribution from both; if one person is silently following, it's not pairing.
- **Conflating pair programming with code review.** They are different things; pair programming substitutes *for* review (the work is reviewed in real time), but the social practices are different.
Further Reading
- [CleanCodePrinciples](CleanCodePrinciples) — Pairing tends to produce cleaner code
- [DebuggingStrategies](DebuggingStrategies) — Pairing accelerates difficult debugging
- [TechnicalLeadershipSkills](TechnicalLeadershipSkills) — Pairing as leadership practice
- [RemoteTeamManagement](RemoteTeamManagement) — Remote pairing specifics
- [SoftwareEngineeringPractices Hub](SoftwareEngineeringPracticesHub) — Cluster index