AI has made it easier to write optimized code on day 0, but it is creating a new problem…
Ask an LLM to write some code, and it will often reach for the most “correct” version - caching, batching, async, configurable strategies. Code that looks staff-level from the first commit.
If you keep probing it to optimize further, it will come up with such absurd optimizations that you may not have even heard of.
Most of these optimizations solve a problem you do not have yet. A function handling 50 records a day does not need a connection pool, a retry queue, and a pluggable backend. It needs to work and be readable.
To be honest, we engineers have always over-engineered, but AI has lowered the cost of writing the complex version to nearly zero, so the lazy default (write the simple thing first) no longer feels lazy. It feels like leaving performance on the table.
The result is codebases full of abstractions nobody asked for. Interfaces with a single implementation. Generic configs for cases that will never change. Vector operations and macros no one asked for.
The skill that matters now is not writing optimized code. It is knowing when to stop optimizing. Premature optimization used to be expensive enough that most people avoided it by default. Now it is one prompt away.
Good engineering judgement is about knowing which optimizations the problem in front of you actually needs.