You open a codebase you’ve never seen before. There are comments everywhere. And yet, somehow, you still have no idea what anything does. Sound familiar? The comments aren’t missing, they’re just useless. They tell you what the code does, which you could figure out by reading the code. What they never tell you is why anyone wrote it this way in the first place. That gap, between what code does and why it exists, is where most software teams quietly lose thousands of hours every year.

This isn’t a laziness problem. It’s a psychology problem. And once you understand it, you can fix it fast. Code comments are more important than the code itself, but only when they’re written with the right mental model.

Why Engineers Write Comments That Don’t Help Anyone

Here’s the core problem: when you write a comment, you are the world’s leading expert on what you just built. You’ve been inside that problem for hours, maybe days. The context is so fresh and vivid in your mind that it’s almost impossible to imagine not knowing it.

So you write a comment that makes perfect sense to you, right now, in this moment. Something like:

// Handle the edge case
if (user.role === 'legacy') { ... }

What edge case? Legacy how? Why does the role matter? You knew the answers when you typed that. Six months later, you won’t. And the next engineer who touches that file never had a chance.

This is sometimes called the “curse of knowledge,” and it shows up everywhere in software. Your brain is so good at compressing familiar information that it literally cannot reconstruct the confusion of not knowing something. You skip steps because the steps feel obvious. They’re not obvious. They were never obvious. They just became obvious to you after you solved them.

This is related to something fascinating about how our brains handle context: the best engineers write code like they’re explaining it to someone who has never touched a computer. That mental shift, from “I know this” to “how would I explain this to a stranger,” is the single most effective tool for writing comments that actually get read.

The Three Types of Comments (and the One That Actually Works)

Most code comments fall into one of three categories.

Type 1: The Narrator. These restate the code in plain English. // Loop through users above a for loop. // Return false if empty above a return statement. These comments are noise. They add visual clutter without adding understanding. Experienced engineers learn to skip them entirely, which trains their eyes to skip all comments, including the useful ones.

Type 2: The Label. These identify what something is without explaining why it’s there. // Payment logic or // Legacy support. Better than narration, but still incomplete. They orient you without actually helping you.

Type 3: The Historian. These are the comments that get saved, quoted in Slack channels, and occasionally praised out loud. They explain context that cannot be inferred from the code itself. Why this approach was chosen over an obvious alternative. What broke when someone tried the obvious thing. What constraint forced an ugly solution. Who made the decision and, if relevant, when.

A Type 3 comment looks like this:

// We use polling here instead of webhooks because the vendor's webhook 
// implementation silently drops events under high load (confirmed with 
// their support team, ticket #4821). Revisit if they fix this in v3.

That comment is worth more than a week of onboarding documentation.

The Practical Framework: Comment for Your Future Self at 2am

Here’s the mental model that actually works. When you finish writing a piece of code and you’re about to add comments, ask yourself one question: If I had to fix a production bug in this function at 2am, six months from now, what would I desperately wish I had written down?

That framing cuts through everything. You stop describing the code and start preserving the knowledge that lives only in your head right now.

Apply it in three passes:

Pass 1: Mark the non-obvious decisions. Anywhere you chose approach A over the more obvious approach B, write one sentence explaining why. This is the highest-value comment you can write.

Pass 2: Flag the landmines. Anywhere something looks wrong but isn’t, say so explicitly. // This looks like it should be >=, but the off-by-one is intentional. See issue #2204. This kind of comment saves hours. It also prevents the next engineer from “fixing” your deliberate choice.

Pass 3: Link to external context. If a business decision, a vendor limitation, or a historical incident shaped this code, reference it. You don’t have to explain the whole story in the comment, you just have to leave a trail.

This three-pass approach takes about ten minutes per significant function. The time it saves across a team compounds quickly, especially on remote teams where async communication is the primary way context gets transferred.

Why AI Tools Make This Problem Worse Before They Make It Better

If you’re using an AI coding assistant, you’ve probably noticed it’s quite good at generating comments. It will look at your function and produce a clear, readable description of what it does. Type 1 and Type 2 comments, automatically, at scale.

This is almost entirely useless. Worse, it creates a false sense of documentation completeness. Your codebase now looks commented. It just isn’t documented in the way that matters.

The reasoning and context that make a comment valuable aren’t in the code for the AI to find. They’re in your head, in a Slack thread, in a post-mortem document, in a conversation that happened in a meeting room two years ago. No model can infer why you made a tradeoff it never witnessed. (And interestingly, the way AI handles uncertainty about its own reasoning process has its own complications, which is worth understanding if you rely on these tools heavily.)

Use AI to generate starter comments if you want. Then treat those as prompts to write the real comment underneath.

The One Habit That Changes Everything

If you take one thing from this, make it this: before you close a pull request, read your own comments as if you are someone who has never seen this codebase. Not someone who’s bad at programming. Someone who’s smart, experienced, and completely missing the specific context that’s currently in your head.

Would your comments help that person? Or would they just confirm what the code already shows?

The gap between those two is exactly where ignored comments live. Closing that gap is one of the cheapest ways to make your team faster, reduce the compounding cost of bugs that come from misunderstood code, and make your own future life considerably less stressful.

Write comments for the person who has to fix it at 2am. Often, that person is you.