Part 4: Best Practices and Pitfalls

Part of the Pair Programming 101 Series

The Argument That Taught Me Everything

Three hours into a pairing session with Jake. Building the payment processing service.

Me: "We should use Stripe's webhook for payment confirmations." Jake: "No, polling is more reliable. We control the timing." Me: "Webhooks are real-time. Polling has delay." Jake: "What if the webhook fails? We miss the payment." Me: "Stripe retries webhooks. It's more reliable than polling." Jake: "I've built this before. Polling works better."

Silence. Tension. Both frustrated.

Then Jake said: "Let's take a 10-minute break."

We came back. Different approach.

Jake: "Show me the Stripe webhook documentation." Me: "Here. They retry up to 3 days with exponential backoff." Jake: "Okay, that's actually more reliable than I thought. But what about our monitoring?" Me: "Good point. We need alerting if webhooks fail." Jake: "And a fallback check. Polling every hour as backup." Me: "Perfect. Best of both approaches."

Result: Better solution than either of us had alone.

Lesson: Disagreements in pairing are valuable. How you handle them matters.

Communication Best Practices

1. Think Out Loud

Bad pairing:

// Driver types in silence for 10 minutes
export async function processPayment(orderId: string) {
  const order = await getOrder(orderId);
  const amount = calculateTotal(order);
  const payment = await stripe.charges.create({
    amount: amount * 100,
    currency: 'usd',
    source: order.paymentToken
  });
  return payment;
}

// Navigator has no idea what's happening
// Misses the bug (amount * 100 should handle cents already)

Good pairing:

Narrating catches bugs before they happen.

2. Ask Questions, Not Commands

❌ Bad communication:

βœ… Good communication:

Questions encourage thinking. Commands shut down collaboration.

3. Celebrate Small Wins

My pairing sessions always include:

Positive reinforcement keeps energy high during long sessions.

4. Regular Check-ins

Every 25-30 minutes:

Check-ins prevent misalignment and catch confusion early.

Role Switching Best Practices

When to Switch

My switching schedule:

1. Time-based (Most common):

2. Task-based:

3. Stuck-based:

How to Switch Smoothly

Bad switch:

Good switch:

Switch at logical boundaries. Not mid-thought.

Handling Disagreements

Framework for Resolving Conflicts

When we disagree, we follow this process:

1. State both positions clearly

2. Look at data/documentation

3. Find hybrid solution

Both of us happier with the solution.

Real Disagreement Examples

Example 1: Error Handling Strategy

Disagreement:

Resolution:

Consistency won. Both felt good about the decision.

Example 2: TypeScript strictness

Disagreement:

Resolution:

Pragmatism won. Set realistic timeline.

Avoiding Fatigue

Pair programming is mentally exhausting. Here's how I stay fresh.

Time Management

My sustainable schedule:

Never pair for more than 2 hours straight. Quality drops dramatically.

Taking Breaks

My break rules:

Breaks maintain focus and prevent mental fatigue.

Recognizing Burnout Signs

Warning signs I watch for:

Don't push through fatigue. Quality suffers and frustration builds.

Common Pitfalls to Avoid

1. Dominating the Session

Bad:

Fix:

2. Not Speaking Up

Bad:

Fix:

Your job as navigator is to catch bugs. Always speak up.

3. Rushing Through Without Understanding

Bad:

Fix:

Both developers must understand the code. Slow down when needed.

My Pair Programming Checklist

Before starting:

During the session:

After the session:

What's Next

In Part 5, we'll cover implementing pair programming at the team level:

  • Introducing pairing to skeptical teams

  • Scheduling pairing sessions

  • Measuring effectiveness

  • Building a pairing culture

  • Scaling across distributed teams

Real experiences from introducing pairing to a 15-person team.


Previous: Part 3 - Tools and Remote Setup Next: Part 5 - Team Implementation β†’ Series Home: Pair Programming 101

This article is part of the Pair Programming 101 series. All examples based on real pair programming experiences using TypeScript, Node.js, and modern development tools.

Last updated