Skip to content

Blog

How Senior Engineers Make Technical Decisions

How senior engineers make technical decisions: weighing trade-offs, naming the real constraint, and knowing when not to build—so the team ships instead of stalling.

How Senior Engineers Make Technical Decisions

Let me start with a story.

Back when I was leading a team, I made it a point to give my junior developers room to grow. So one time I gave one of them a free hand — pick up some tickets, make a few calls on your own, take ownership. He did well on a lot of it. That's the whole point of handing people the keys: they learn by deciding, not by waiting for me to decide for them.

Then one task quietly went sideways.

We had a client with a WordPress site. On the dashboard there was one of those familiar little warnings: your PHP version is getting old, consider updating it. So my junior, being the responsible guy he is, went ahead and did the upgrade.

And then the task just sat there. In progress. In progress. In progress. Day after day. Until I finally stepped in and asked, "Hey, what's going on with this one?"

Turns out the moment he upgraded PHP, the whole thing fell apart. Old code that didn't play nice with the new version. Plugins breaking left and right — plugins we didn't even build. He'd been stuck in debugging hell for the better part of a week, trying to glue everything back together.

So I asked him the obvious question: "Why did you upgrade it in the first place?"

"It wasn't even in the Jira ticket," he admitted.

"Okay — did you assess the outcome? Did you stop and think about what would happen to the site if you ran that upgrade?"

"No. I just upgraded it. And now everything's falling apart."

Here's what I told him: this was never a life-or-death situation. Nobody was going to lose anything if that PHP version stayed where it was. The site worked. The client wasn't blocked. A warning on a dashboard is not a mandate. He could have simply left it alone — and that would have been the better decision.

But he saw a notice, assumed it had to be done, and walked straight into a week of work nobody asked for.


Now let me tell you about a second time, because it makes the same point from a different angle.

We had a cron job that had been stuck for a while — something like fifteen days. Because it was down, the team had been sending certain emails out manually that whole time just to keep things moving. Annoying, but survivable.

So I asked the same junior, "Can you take a look and see what's going on?"

And he did. He found the problem and got the cron job running again. Good — except that's only half the job.

Because here's the thing he didn't ask: "If I turn this back on, what happens to everything connected to it?" Those fifteen days of emails that the team had already sent by hand were never marked as sent in the database. So the moment that cron job came back to life, it was perfectly happy to fire off all of those emails again — to people who'd already received them.

He fixed the cron job. He didn't think about the database state behind it. And that one missing question was the difference between a clean fix and a mess that goes out to real users.


I'm not telling these stories to dunk on a junior engineer. He's sharp, and honestly, both of these are mistakes I made myself earlier in my career. I'm telling them because together they point at the thing nobody really teaches you on the way up.

The gap between a junior engineer and a senior one usually isn't raw skill. It's not who knows more syntax or more frameworks. It's the questions you ask before you start typing. That, more than anything, is what making good technical decisions comes down to.

The difference isn't coding skill

Look closely at both of those stories and you'll notice they failed for the exact same reason. It wasn't that the work was too hard. My junior was perfectly capable of running a PHP upgrade and perfectly capable of restarting a cron job. He did both without breaking a sweat.

The failure was that he acted before he understood the consequences. In both cases the technical task was easy. The decision behind it was the hard part, and that's the part he skipped.

This is the line that separates the two mindsets:

  • A junior engineer asks, "Can I do this?"
  • A senior engineer asks, "Should I do this?"

"Can I" is a question about ability. Once you've been writing code for a year or two, the answer is almost always yes. "Should I" is a question about judgment, and that one takes much longer to learn. The rest of this article is really a breakdown of how senior engineers answer that second question.

Senior engineers start with the outcome

When a junior gets a task, the first thing they reach for is a solution. When a senior gets a task, the first thing they reach for is a question: what problem are we actually trying to solve?

This sounds obvious, but solution-first thinking is everywhere. A warning shows up on a dashboard, so we fix the warning. A library has a newer version, so we upgrade. A function looks a little ugly, so we rewrite it. None of those are problems. They are observations, and observations are not automatically work.

That was the whole issue with the PHP upgrade. A warning is a suggestion. A suggestion is not a ticket. Before any of that becomes real work, someone has to ask what outcome we're chasing and whether it's worth the cost.

It helps to sort what lands on your plate into three buckets:

  • Business problems: something is costing money, blocking customers, or holding back growth.
  • Technical problems: something is genuinely unstable, insecure, or about to break.
  • Cosmetic problems: something simply looks old, untidy, or imperfect.

The PHP warning was cosmetic dressed up as technical. The site worked. Customers were fine. Nothing was at risk. It only felt urgent because the dashboard made it feel that way.

A senior engineer doesn't see a PHP warning. They see a decision with consequences.

They identify the real constraint

Once you know the outcome you want, the next question is, what is actually preventing success right now? Every project is held back by something, but it's rarely the thing you're staring at.

The real constraint is usually one of these:

  • Time
  • Budget
  • Reliability
  • Performance
  • Team capacity
  • Customer impact

Here's the part that takes experience to feel: at any given moment, one of these dominates. There is a single constraint that matters more than the rest, and energy spent anywhere else is mostly waste. Senior engineers spend their effort on the dominant constraint. Juniors spend it on whatever is most visible or most fun.

If customers are waiting three days for a feature, shaving 20ms off an API call isn't solving the real problem.

They think about what happens after the fix

This brings me back to the cron job. Restarting it was first-order thinking: the job was down, so turn it back on. The senior move is to ask one more question. If I make this change, what else changes?

In that case, the answer lived in the database. The emails from the last fifteen days had been sent by hand, but they were never marked as sent. So flipping the cron job back on wouldn't just resume normal service. It would happily resend every one of those emails to people who already got them.

The fix was correct. The thinking around the fix was incomplete. Before changing anything, the habit to build is simple: ask what depends on this.

Plenty of everyday changes carry these hidden second-order effects:

  • Restarting stuck jobs
  • Running data migrations
  • Touching payment systems
  • Changing email systems
  • Flipping feature flags

None of these live in isolation. The change you make is rarely the whole story. What it sets in motion downstream usually is.

They evaluate trade-offs, not perfect solutions

This is the heart of senior-level decision making, so it's worth slowing down on. Juniors look for the right answer. Seniors accept that there usually isn't one, only a set of trade-offs where every choice costs something.

Most real decisions are a tension between two reasonable things:

  • Speed versus quality
  • Simplicity versus flexibility
  • Build versus buy
  • Short-term versus long-term

You don't get to win all of these at once. Picking one almost always means giving up a little of the other, and pretending otherwise is how projects quietly fall behind. The skill isn't finding a choice with no downside. It's choosing which downside you can live with.

The best solution is rarely the technically pure one. It's the one that creates the most value for the least cost.

They know when not to build

One of the biggest shifts from mid-level to senior is learning to not build things. Engineers love building. It's the fun part, it feels productive, and it's what we're trained to do. But the business doesn't want code. It wants outcomes, and code is just one expensive way to get them.

Before writing something new, a senior looks around first:

  • Is there an existing tool that already does this?
  • Is there a library we can lean on?
  • Is there a workflow that already handles it?
  • Would a small temporary solution buy us enough time?

The PHP story is really a version of this. The most valuable thing my junior could have done was nothing. Leave the working site alone and move on to work that mattered.

Sometimes the most senior decision in the room is leaving the codebase exactly as it is.

They reduce risk before they reduce effort

Juniors optimize for getting done quickly. Seniors optimize for not blowing things up. When the stakes are real, reducing risk comes before saving effort, every time.

In practice that looks like:

  • Testing your assumptions before you trust them
  • Running a small experiment instead of a big bang change
  • Making sure there's a way to roll back
  • Hiding risky changes behind feature flags
  • Trying it in staging before it ever touches production

If the cron job had been treated as risky, a quick dry run would have surfaced the duplicate-email problem before a single real person was affected. That is the whole point of working this way.

Senior engineers don't bet the company on a single deployment.

Incremental releases, canary deployments, and dry runs all exist for the same reason: to make a mistake cheap instead of catastrophic.

They gather context before giving answers

A junior often wants to prove they know the answer. A senior wants to make sure they're answering the right question first. That means slowing down at the start to gather context:

  • Talk to the people asking for the work
  • Ask the product questions, not just the technical ones
  • Understand who it actually affects
  • Investigate before you implement

You can hear the difference in one sentence:

  • The junior says, "I know how to do this."
  • The senior says, "Help me understand why we're doing this."

Both of my stories would have ended differently with one quick conversation up front. "Do we actually need this PHP upgrade?" and "If I restart this job, what happens to the emails we already sent?" are not hard questions. They just have to be asked before the work, not after.

They optimize for the team, not their ego

The last shift is the quietest one. Junior engineers often write code to impress. Senior engineers write code to be understood. The audience isn't other clever engineers. It's the teammate who has to read this at 2am six months from now.

So they optimize for:

  • Maintainability
  • Readability
  • Knowledge sharing
  • Simplicity

Clever code feels great to write and creates a cost every time someone else has to touch it. The goal was never to look smart. The goal is to help the team move faster, today and a year from now.

A senior engineer isn't judged by the code they write. They're judged by the problems the team no longer has.

A checklist before making any technical decision

If you take one practical thing from this article, take this. Before you change anything, run through these questions. They take two minutes and they would have saved a week in both of my stories.

  1. What problem am I actually solving?
  2. What happens if I do nothing?
  3. Who is affected by this change?
  4. What systems depend on it?
  5. What's the worst thing that could happen?
  6. Can I roll it back?
  7. Is there a simpler solution?
  8. What is the real constraint here?
  9. Am I solving a business problem or a technical curiosity?
  10. Does this create more value than risk?

None of these are about coding ability. Every one of them is about judgment, and that's exactly the point.

Why I still let my juniors make decisions

After stories like these, you might think the lesson is to keep juniors on a short leash. It isn't. I still hand them the keys, on purpose.

Good judgment isn't something you can hand someone in a document. It's trained. You build it by making decisions, getting some of them wrong, and having someone ask you the question you forgot to ask yourself. That's all the PHP upgrade and the cron job really were. Cheap lessons in a safe place.

Making good technical decisions was never about knowing more than everyone else in the room. It's about pausing long enough to ask the right question before you spend a week answering the wrong one.

← Back to all posts