How to optimize code performance with AI coding agents
"Make this page faster."
Ten minutes later the diff looks industrious. A loop unrolled. Two map calls
fused into one pass. A memo wrapped around a pure function. A commit message
promising a significant performance improvement.
You reload the page. Still 4.2 seconds.
Nothing in that diff was wrong. It just wasn't where the time went. The time went into one query that runs once per row, four hundred times, and the agent never saw it, because it was reading your code instead of watching it run.
Agents optimize what looks slow, not what is slow
Slowness is a property of execution: what the database did, what the network waited on, what the cache missed, how much JavaScript the browser had to parse before it could paint. None of that is visible in the source. What is visible in the source is code that pattern-matches to "expensive": nested loops, string concatenation, a regex.
So that's what gets optimized. Confidently, competently, and usually at the wrong end of the file.
Agents are genuinely good at the mechanical half of this work: rewriting a hot function, batching queries, adding an index. They're bad at choosing the target. So stop letting them choose it from memory.
No number, no optimization
One rule fixes most of this: the agent isn't allowed to touch performance code until it can quote a measurement.
Not an estimate. Not "this looks O(n²)". A number, produced by running something:
- A timing harness or benchmark around the slow path.
- A profiler run: flame graph, sampled stacks, whatever your stack gives you.
- The query log, with counts and durations.
- The browser's performance panel or a Lighthouse run for frontend work.
This is the same discipline that makes debugging with agents work instead of producing a pile of speculative null checks. Reproduce it, measure it, then touch it.
The measurement also gives you a definition of done. "Faster" is unfalsifiable. "P95 under 300ms on the 10k-row fixture" is a task an agent can finish and you can verify in one command.
The four-step loop
1. Get a baseline, and write it down. Same machine, same data, same warm-up. If a number can't be reproduced twice, it isn't a baseline. It's noise, and you'll spend the afternoon chasing a 12% swing that was your laptop throttling.
2. Make the agent name the hotspot before it edits. Have it report the profile and say, in one line, where the time actually goes and why. Read that line. Half the time it's wrong, and you've just saved yourself reviewing a 400-line diff aimed at the wrong function.
3. Change one thing. A single hotspot, a single mechanism. Batched changes make attribution impossible: three landed together, one helped, one hurt, and now you can't tell which was which.
4. Re-measure, then keep or revert. Under the same conditions as the baseline. If the win doesn't show up in the number, revert it, even if the code reads better. Especially then. Unmeasured wins are how a codebase accumulates complexity nobody can justify or safely remove.
Then lock it in with a benchmark in CI, or the gain erodes over the next six months. Same argument as test-driven development with agents: the agent should be able to prove its own work without you.
The failure modes worth naming
Correctness quietly traded away. Caching that never invalidates. A dropped
ORDER BY because it looked "redundant". Fast and wrong is a worse bug than slow
and right, because slow is visible.
Caching over a fix. A cache in front of an N+1 is a slower N+1 with a staleness bug attached. Ask what the code does on a cold cache before accepting it.
Optimizing on dev-sized data. Ten seeded rows hide the exact behaviour that melts at ten thousand. Benchmark against realistic volume or don't bother.
Micro-optimizing the 2%. A function can get 40% faster and move your page load by nothing at all. Amdahl's law doesn't care how clean the diff is.
"Fast enough" never being an option. Sometimes the honest answer is that the endpoint is fine and the problem is elsewhere. An agent told to optimize will always find something to optimize. Give it permission to report that the target is already met.
Where the workflow lives
Measure → change → re-measure is a loop, and loops are miserable to run across scattered terminal tabs. That's the shape SanuDesk is built for.
It's a desktop app that tiles your Claude Code, Codex and Gemini sessions into one grid, with a Kanban board they pull work from. Each hotspot becomes a card with the baseline and the target number written into its acceptance criteria, so the brief is measurable before an agent starts. Deploy three cards and three agents work three separate hotspots in parallel, each in its own clean session, instead of one agent holding your whole performance backlog in one filling context window.
Loops handle the part everyone skips: a scheduled run that re-executes the benchmark suite, compares against the recorded baselines, and opens a card when something regressed: the recurring-chore pattern applied to speed, so regressions surface in a week rather than in a support ticket. It drives the agent subscriptions you already pay for, and the free tier doesn't need an account with us.
Start with one number
Pick the slowest thing you shipped this month. Before you ask any agent to improve it, get one honest measurement and write it at the top of the task.
That single line changes the whole session: from an agent guessing at what looks expensive, to an agent that can tell you whether it actually helped.
Download SanuDesk free and point a workspace at your repo, or see how the grid, the board and Loops fit together on the features page.