DEV Community

Cover image for The Cognitive Budget: How I Write Code I Can Actually Maintain
Doogal Simpson
Doogal Simpson

Posted on • Originally published at doogal.dev

The Cognitive Budget: How I Write Code I Can Actually Maintain

You’ve been there. You open a file you wrote three months ago. You stare at the function. You squint. You scroll up, then down, then up again.

You know you wrote it. You know it works. But right now, looking at it, you feel… slow.

Here is the hard truth: You are not a computer.

The machine running your code has gigabytes of RAM. It can hold a million variables in perfect suspension without breaking a sweat. It doesn't care if a function is 10 lines or 1,000 lines.

You don't have that luxury.

We have a working memory "buffer" of about five to seven items. That is your Cognitive Budget.

Every time you write a function that requires you to remember the state of a local variable, a global flag, a loop index, and a date calculation all at once, you are using up slots in that budget.

When you exceed that budget, you start "dropping packets." You miss bugs not because you are bad at logic, but because you are physically incapable of holding that much context in your head at once.

This is the most critical concept in "Teach" mode refactoring: We must code for the human limitations, not the computer's capabilities.

The Trap: The "Kitchen Sink" Function

The most common way Juniors blow their Cognitive Budget is the "Kitchen Sink" function.

We try to calculate everything in one pass to be "efficient." We think, "I’m already looping through the array, I might as well check the dates and format the output and validate the user."

The result is a variable soup.

The Code: Blowing the Budget

Look at this function. To understand it, you have to track out, t, i, the state of users, and the complex date logic inside the if statement simultaneously.

// BEFORE: The Kitchen Sink
// We have to track `t`, `i`, `out`, and the state of `users` simultaneously.
function getActiveEmails(users) {
  let out = [];
  let t = new Date();

  // Slot 1: Loop logic
  for (let i = 0; i < users.length; i++) {
    // Slot 2, 3, 4: Complex condition with nested math
    if (users[i].isActive && users[i].lastLogin > t.setMonth(t.getMonth() - 1)) {
      // Slot 5: Null checking
      if (users[i].email) {
        // Slot 6: Mutation
        out.push(users[i].email);
      }
    }
  }
  return out;
}
Enter fullscreen mode Exit fullscreen mode

If you are interrupted while reading line 6, you lose the entire mental stack. You have to start over. This code is fragile because it demands 100% of your focus to understand.

The Solution: The Bite-Sized Buffet

The goal of a Professional Junior is to keep the reader's mental load under that 5-item limit at all times.

We do this by Quarantining Complexity.

We don't remove the complexity (the business logic still needs to happen), but we hide it inside named functions. We break the logic into concepts.

The Code: Balancing the Budget

Here is the same logic, refactored to respect your brain's RAM.

// AFTER: The Cognitive Budget Balanced

function getActiveEmails(users) {
  // We don't have to remember HOW "isUserActive" works. 
  // We just trust the name.
  return users
    .filter(isUserActive)
    .map(u => u.email);
}

// The complexity is quarantined here.
// We can focus on this logic in isolation without worrying about the loop.
function isUserActive(user) {
  const cutoff = new Date();
  cutoff.setMonth(cutoff.getMonth() - 1);

  return user.isActive && user.lastLogin > cutoff;
}
Enter fullscreen mode Exit fullscreen mode

Why This Wins

  1. Reduced Scope: When I look at getActiveEmails, I only need to understand the flow of data. I don't need to know the math of the date calculation. My mental load is 2 items (filter, map).
  2. Quarantined Logic: When I look at isUserActive, I don't need to care about loops or arrays. I only care about one user.
  3. Declarative vs. Imperative: The "Before" code tells the computer how to do it (loop, increment, check, push). The "After" code tells the human what is happening (filter active users, map to emails).

The Pro Move:
We strive for code that is so obvious it looks boring. When the solution is obvious, bugs have nowhere to hide.

Stop trying to prove how smart you are by juggling ten variables in your head. Prove how professional you are by making sure your teammates (and Future You) never have to.


Stop writing code just to please the compiler.

This article was an excerpt from my handbook, "The Professional Junior: Writing Code that Matters."

It’s not a 400-page textbook. It’s a tactical field guide to unwritten engineering rules.

👉 Get the Full Handbook Here

Top comments (0)