Open a random service and grep for // TODO: optimize or // this is slow. Half of those comments were written before the index existed, before the table was small, or before the query got rewritten. They sit there as ambient guilt.
Hand that codebase to an agent and the comment becomes a spec. It reads // this list endpoint is O(n^2), add caching, nods, and twenty minutes later you have a Redis layer, a TTL, an invalidation hook, and a PR titled "perf: cache slow list endpoint."
The test suite passes. The CI is green. The PR description is clean.
Nobody ran the profiler.
The comment was true in 2022
The function was genuinely slow once. Then someone added an index, then someone else rewrote the query, then the table shrank when a nightly job moved old rows to an archive. Endpoint p95 went from 800ms to 12ms. The comment stayed.
Now the agent has put a 60-second TTL cache in front of a 12ms endpoint. The first request is slower (cache miss + Redis round trip). Subsequent requests return stale data for up to a minute. And every time someone changes the underlying data source, they have to remember to invalidate a cache that was never needed.
The cost of the cache is now higher than the cost of the thing it was caching.
Why agents do this
Agents are trained to follow instructions. A comment in the code is an instruction. It doesn't cross-check the comment against reality because that requires leaving the editor, running a profiler, reading flame graphs, and judging whether the problem still exists.
That's expensive. Writing a cache is cheap. The cache also reads like work — it adds files, it adds a dependency, it adds a commit that says "perf." It's the kind of change that looks good in a review queue and bad in a production incident two weeks later when a user asks why their new row didn't show up.
The cheap gate I've started asking for
Before approving any agent-authored "perf" change, ask for one line: the measured p95 before and after, on a realistic load.
If the answer is "it was slow, I trusted the comment," the PR goes back. If the answer is a real number from a real run, you can have an actual conversation about whether the cache is worth the invalidation burden.
This is the same instinct behind the cheap gates I keep coming back to in this column: ask the agent to show you the command, the output, and the before/after. Don't let it declare a problem solved on the basis of a comment that predates your current on-call rotation.
Same trap, different shape
It's not just performance. Agents will "fix" a commented-out function, migrate a deprecated API that's already on a roadmap replacement, and add retries to a call that already has retries one layer up. Each one follows a stale signal. Each one adds surface area.
The pattern is the same: the agent treats the nearest written instruction as ground truth, and doesn't ask whether the situation has changed.
When the work crosses into API behavior, I've stopped trusting my own memory of what changed and what didn't, and just re-run the spec against the live endpoint — the same way I'd want the agent to run the profiler before adding a cache. The point isn't the tool; it's the habit of measuring before you build. You can read more about that approach at powerduck.com.
What's the most elaborate fix you've seen an AI write for a problem that no longer existed?
Top comments (0)