Skip to content

guide

Rubber Duck Debugging: Why Explaining Code to a Toy Actually Works

Talking through broken code out loud forces you to slow down and articulate assumptions you didn't know you were making.

· 7 min read

A developer desk with a laptop, notebook and space for a desk toy

Devs At Home is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program. We earn from qualifying purchases. This never affects what we recommend or what we say about it.

What Is Rubber Duck Debugging

Rubber duck debugging is explaining your code line-by-line to an inanimate object until you spot the bug yourself. The listener doesn't need to understand programming. It doesn't need to be a rubber duck. A cardboard box works. So does a potted plant.

The method appeared in The Pragmatic Programmer in 1999, where Andrew Hunt and David Thomas described a programmer who carried a rubber duck and debugged by talking to it. The duck never answered. That was the point.

You explain what the code is supposed to do, then what it actually does, line by line. Usually you find the problem before you finish explaining. The act of verbalising forces you to examine assumptions you didn't know you were making.

Why Rubber Duck Debugging Works

Your internal monologue runs faster than you can speak. When you read code silently, you skip over the parts that seem obvious. You fill in gaps. You see what you expect to see rather than what's actually there.

Speaking out loud slows you down. You have to complete each sentence. You can't skim a for-loop the way you can when reading silently — you have to say "this iterates from zero to length minus one" and then you hear yourself say "length minus one" and realise length is off by one.

The constraint is cognitive, not auditory. Typing your explanation in a chat window to yourself works nearly as well. Anything that forces serial processing instead of the parallel assumptions your brain makes when reading code you wrote.

Pair programming achieves a similar result, but rubber ducking doesn't require another person's time or attention. You can do it at two in the morning without waking anyone.

The Articulation Gap

The bug is often in the space between what you think the code does and what you can actually say it does. If you can't explain a function clearly, you probably don't understand it clearly. The duck makes that visible.

Variables named temp or data are fine when you're thinking fast, but when you have to say out loud "then I set temp to the value of data" you notice you've lost track of what temp represents. Renaming the variable usually fixes two other bugs you hadn't noticed yet.

This is why the method works even though the duck doesn't respond. You're not looking for advice. You're looking for the friction between your mental model and the code that's actually running.

When to Use Rubber Ducking Programming

Use it when you've been staring at the same twenty lines for fifteen minutes. When you've added print statements and the output makes no sense. When the bug is clearly right there but you can't see it.

It works best on logic errors — off-by-one, wrong variable, inverted condition, bad assumption about input. It's less useful for environment issues, race conditions or anything involving infrastructure you don't control.

You don't need an actual duck. Most developers use whatever is on the desk: a coffee mug, a monitor, a coworker's back if they're wearing headphones. The object is a focal point. It gives you something to direct your explanation toward instead of staring at the screen.

Before You Ask Someone Else

Rubber duck first. If you still don't find it after explaining the code out loud, then ask a person. You'll ask a better question because you've already articulated the problem. They'll spend less time getting oriented and more time actually helping.

This is common etiquette in open-source projects and developer communities. Explaining your debugging process in the question shows you've done the work. The act of writing that explanation often leads you to close the issue before posting it.

How to Rubber Duck Debug Effectively

Start before the bug. Explain what the function is supposed to do, in plain sentences. If you can't do that without looking at the code, you're debugging from an unclear specification.

Then go line by line. Say what each line does and why it's there. Don't paraphrase. If the code says i < array.length say "while i is less than array length" not "while there are items left." The bug is often in the gap between the two.

When you hit the bug, keep going. Explain the next five lines anyway. Sometimes the problem is later than you think, or there's a second bug that will reappear once you fix the first.

What to Say

Describe data flow, not syntax. "This takes the user input and splits it on commas" is more useful than "this calls the split method with comma as the argument." You're trying to surface your assumptions, not read the code aloud word for word.

Name the types. "This returns a string" or "this array contains user objects." Type mismatches hide easily in dynamic languages, and saying the type out loud often exposes the problem immediately.

If you hear yourself saying "this probably" or "I think this," stop. That's the assumption. Verify it. Add a print statement or open the debugger and check whether what you think is happening is actually happening.

Common Mistakes

Skipping the "obvious" parts defeats the method. The bug is in the obvious part. That's why you can't see it. If you're going to skip lines, skip the ones you just wrote today. Explain everything older than that.

Summarising instead of articulating is the other failure mode. "This loop processes the data" doesn't force you to think. "This loop starts at index one, not zero, and iterates to the length of the input array" makes you notice you're skipping the first element.

Explaining to a person too soon wastes their time and yours. If you haven't tried the duck, you're asking them to be your working memory instead of using the method that doesn't require coordination.

When It Doesn't Work

If you've explained the code twice and still don't see it, the problem is probably not in the code you're looking at. Check the function that calls this one. Check what data it's receiving. Check whether the bug is in your mental model of what the system does, not in this specific function.

Take a break. Make coffee. The solution shows up in the shower because your brain stops actively searching and switches modes. Rubber ducking is a structured version of that mode switch, but sometimes you need the actual break.

Variations and Alternatives

Writing the explanation instead of speaking it works nearly as well. Open a scratch file and type what each function does and why. Some developers keep a debugging journal — a text file where they explain the problem before they start fixing it. Fixing is often unnecessary once the explanation is written.

Teaching someone else achieves the same cognitive shift. If you're onboarding a junior developer, have them sit with you while you work through a bug. Explaining your process helps both of you, and you'll spot mistakes you wouldn't have noticed alone.

Diagramming the data flow on paper serves a similar purpose. Draw boxes and arrows showing what data goes where. The act of converting code to a diagram forces the same kind of serial, explicit processing that speaking does.

Pair Programming vs Rubber Ducking

Pair programming provides a real person who might catch things you miss, but it requires coordinating schedules and maintains constant social overhead. Rubber ducking is available immediately and costs nothing but time.

Use pairs for complex architectural decisions or unfamiliar territory where another perspective helps. Use the duck for implementation bugs where you know the domain but lost track of the details.

Does It Work for Non-Developers

Explaining a problem out loud works in any domain where complexity hides errors. Writers talk through plot holes. Designers explain interface flows to spot inconsistencies. Accountants read spreadsheet formulas aloud to find mistakes.

The method is domain-agnostic. It works whenever expertise makes you skip steps mentally that turn out to contain the error. Developers use it more visibly because code either works or doesn't, with no middle state, so the debugging process is more explicit.

If you build mental models to solve problems, rubber ducking forces you to externalise those models where you can inspect them. The duck itself is optional. The externalisation is not.

Should You Actually Buy a Rubber Duck

You don't need one. Any object works. But plenty of developers keep a duck on the desk anyway because it signals to coworkers that you're debugging and shouldn't be interrupted. It's a physical indicator of mental state.

Some teams buy ducks for the whole group. It becomes shorthand: "I'm going to duck this" means "I'm going to think it through before asking for help." The shared language makes debugging less frustrating because there's an explicit step between "I'm stuck" and "I need someone else."

If you want one, get the cheapest rubber duck you can find. The four-dollar ones from a toy store work exactly as well as the twenty-dollar programmer-themed ones. It's going to sit on your desk collecting dust either way. Spend the saved sixteen dollars on better coffee.

One email a week

New reviews, teardowns and the occasional deal worth knowing about. No spam, unsubscribe any time.