
I once spent a full day shaving forty milliseconds off a function that ran, at most, twice a month. I was proud of it. I shouldn't have been.
That day is a perfect snapshot of who I used to be: an engineer who optimized everything, reflexively, whether it mattered or not. I confused making code fast with making code good, and the two are not the same.
Letting go of that compulsion is one of the best things I've done for my career. Here's what changed.
I stopped optimizing everything because almost none of it mattered, and the chase had real costs: slower delivery, more complex code, and bugs introduced in pursuit of speed nobody needed. Now I optimize only what I've measured to be slow on a path that's actually hot. Everything else, I keep simple.
The short version:
The reflex feels responsible. You see a loop and think "I could make this faster." You see a database query and itch to add a cache. It feels like craftsmanship.
But it's usually a trap, for a simple reason: the vast majority of your code doesn't run often enough or slowly enough for its performance to matter at all. A function that takes ten milliseconds and runs once a day is, for all practical purposes, instantaneous. Making it take five milliseconds is a rounding error you paid real time to achieve. Knowing where not to spend effort is one of the least-discussed parts of the brutal truth about becoming a senior developer — judgment about what to ignore is judgment.
Worse, the optimized version is almost always more complex. The simple loop became a clever, hard-to-read construction. The straightforward query grew a caching layer with its own invalidation bugs. You traded clarity — which you need constantly — for speed you'll never notice.
I was optimizing my code and pessimizing my codebase. Faster functions, slower team.
Photo by Luke Chesser on Unsplash
The hidden bill for chronic optimization is bigger than the wasted hours, though there were plenty of those.
It slowed down delivery. Time spent polishing the speed of code that didn't need it was time not spent shipping things users wanted. Every optimization sprint was a feature that didn't happen.
It added bugs. Optimized code is trickier code, and trickier code breaks in trickier ways. Some of my nastiest production incidents came from "performance improvements" — a cache serving stale data, a clever batching scheme losing records under load. The simple version would never have done that.
It made the code hostile to change. Heavily optimized code is rigid. It's tuned for one path and resents being modified. When requirements shifted, the clever fast version was far harder to adapt than the boring slow one would have been.
I was paying, in three currencies, for speed that delivered nothing.
The fix is old advice that I'd heard a hundred times and never truly internalized: don't optimize until you've measured.
Here's how I actually apply it now:
The discipline is in steps two and three. The instinct is to skip straight to optimizing based on a hunch. The hunch is usually wrong, and acting on it costs you complexity for nothing.
| Approach | What you spend | What you get |
|---|---|---|
| Optimize everything up front | Lots of time, lots of complexity | Speed nobody needed + new bugs |
| Optimize on a hunch | Some time, some complexity | Often the wrong target |
| Measure, then optimize the hot spot | A little time, targeted complexity | Real speed where it matters |
I want to be clear: performance matters enormously sometimes. I'm not arguing for slow software. I'm arguing against indiscriminate optimization.
There are paths where speed is the whole point — a request hit thousands of times a second, a loop processing millions of rows, the thing standing between a user and the content they're waiting for. On those paths, you optimize hard, and you're right to.
The difference is that you know those paths are hot, ideally because you measured. You're spending your optimization budget where it converts to real value, instead of sprinkling it evenly across code that doesn't care.
Performance is a budget, not a virtue. Spend it on the few paths that matter and you look brilliant. Spread it everywhere and you just look busy.
This is also where good developer tools and automation pay off. A profiler that points straight at the hot function, performance monitoring that tells you what's actually slow in production, AI assistants that can suggest a faster approach for a specific bottleneck — these let you aim. Google's web.dev performance guidance is built on the same principle: measure real user-facing metrics first, then optimize the thing the data points at. The skill isn't optimizing. It's knowing where to — the same measure-before-you-act discipline I lean on in the testing habit I wish I'd started earlier.
Photo by Ilya Pavlov on Unsplash
Dropping the optimization reflex gave me back more than time.
My code got simpler, and simple code is easier to read, change, and trust. I shipped faster, because I stopped polishing things nobody was waiting on. And paradoxically, my software's overall performance got better — because I now had the time and focus to optimize the few paths that genuinely mattered, hard, instead of spreading thin effort across everything.
The biggest gain was mental. I stopped treating every line as a performance problem to solve and started treating most lines as simple instructions to keep clear. The job got lighter.
I don't want to leave the impression that I stopped caring about performance. I care about it more now — I just spend the caring where it pays.
When I finally measured my application properly, the results were humbling. The forty-millisecond function I'd lovingly optimized wasn't even in the top fifty slowest things. The real bottleneck was somewhere I'd never have guessed: a chatty pattern that quietly made dozens of tiny database trips to render a single page. Nobody had optimized it because it didn't look slow. It just was.
Fixing that one thing did more for the app's actual speed than every micro-optimization I'd ever performed, combined. One measured fix on a genuinely hot path beat a hundred hunches.
That's the pattern, over and over. The optimizations that move the needle are almost never the ones your intuition flags. They're boring, structural, and invisible until you measure — a repeated query, a missing index, a payload that's ten times bigger than it needs to be, a thing done in a loop that could be done once.
So my advice isn't "stop optimizing." It's "stop guessing." Spend an hour with a profiler before you spend a day with your cleverness. The profiler will point at something you didn't expect, and that something will matter ten times more than the thing you were itching to polish. Aim before you fire, and you'll hit targets you didn't even know were there.
If trading reflexive cleverness for measured judgment sounds useful, it's worth following along for more of these hard-earned shifts.
Q: Isn't it lazy to not optimize code? It's the opposite. Optimizing everything is the easy, reflexive move — it feels productive while mostly wasting effort. Choosing not to optimize what doesn't matter, so you can pour real effort into what does, takes more judgment and discipline, not less.
Q: How do I know if a path is hot enough to optimize? Measure it. Profile your application under realistic load and let the data point at the slow spots. If you're guessing, you're almost certainly wrong — bottlenecks are notoriously counterintuitive. The hot paths reveal themselves the moment you actually look.
Q: What about writing efficient code from the start — isn't that good? There's a difference between efficient and optimized. Writing reasonable, non-wasteful code by default is good hygiene. Contorting code for speed before you've measured a need is the trap. Default to clear and sensible; reserve the contortions for proven bottlenecks.
Q: Doesn't this lead to slow software over time? Not if you measure. The slow-software risk comes from never checking, not from declining to micro-optimize. Profile periodically, watch production performance, and attack real bottlenecks decisively. Targeted optimization beats scattered optimization on overall speed every time.
I stopped optimizing everything because everything didn't need it, and the chase was quietly costing me velocity, simplicity, and stability. The work that looked like craftsmanship was mostly busywork wearing a nice coat.
Write the simple version. Ship it. Measure. Optimize only the proven hot path, only as far as you need to, and leave the rest gloriously, boringly plain.
Next time your fingers itch to make something faster, pause and ask: have I measured that this is slow, on a path that's actually hot? If the answer is no, the best optimization you can make is to walk away and ship.
I spent years saving the hardest task for when I 'felt ready.' Doing it first instead quietly fixed my focus, my dread, and my output.

I tracked every distraction for a week and was horrified by what I found. Then I fixed the three that mattered most.

No following, no network, no luck. Just an unglamorous system I ran for eighteen months. Here's exactly what I did.

Comments
Sign in to join the conversation
No comments yet. Be the first to share your thoughts!