Cloudflare Cut Its AI Code Review Bill 68%. Most of the Savings Were Hiding in Plain Sight
Five ordinary fixes, one honest quality check, and a checklist you can run on your own agents this week
AI agent bills have a habit of growing while nobody touches anything. No new feature ships, no new team signs up, and the cost per job still climbs month after month.
Cloudflare just published the receipts for one of those climbs, and for the way back down. Its internal AI code reviewer cost $1.22 per review in March and $2.32 in August, according to a post by Ryan Skidmore dated October 19. By October the team had it at $0.77, down 68% from $2.43 (the average of its two most expensive weeks), while the median review got faster, from 4 minutes 9 seconds to 1 minute 32 seconds.
The result is a practical lesson for anyone running agents: the money mostly leaked through ordinary gaps, not through the model's sticker price. The second lesson is the one most teams skip: a cheaper agent only counts if you also check what it stopped catching. Here is what Cloudflare found, in plain terms, and how to look for the same leaks in your own setup.
What Cloudflare was actually paying for
The reviewer is a small team of AI agents. A coordinator agent reads a merge request (GitLab's name for a pull request) and hands pieces of it to specialist reviewers for code quality, security, performance, documentation, and Cloudflare's internal standards. It runs on OpenCode, an open-source coding agent. Every reviewer has run on Anthropic models since early August; per the post, the coordinator now uses Opus 5.5 and the code quality, performance and security reviewers use Sonnet 5.5, while the internal standards reviewer ran on Claude Opus 4.7 in August.
Most cost write-ups stop at "tokens are expensive." Cloudflare broke the bill down first. Before the work began, output tokens were 23% of spend, cache writes were 43%, and cache reads were 34%.
That split is the first useful idea in the post. If more than three quarters of your bill is the cost of storing and re-reading the same prompt, the model's per-token price is not your main problem. How you send the prompt is.
Fix one: make the shared part of the prompt actually shared
Prompt caching is the feature that lets a provider remember the start of a prompt it has already seen. Think of it like a photocopier that charges full price for the first copy of a page and pennies for every copy after that. On Anthropic's API, cache reads cost a fraction of normal input (0.1 times the base price on most models, 0.05 times on Opus 5.5 and Sonnet 5.5), while writing a new cache entry costs 1.25 times the base price for the default five-minute cache.
The catch is that caching only works on an identical beginning. Change one character before a cache marker (a breakpoint) and that cached chunk, plus everything after it, has to be paid for again. Very short prompts below a model-specific minimum length are not cached at all.
Cloudflare's reviewer was building each agent's system prompt as one block: the agent's instructions, then an environment section with details like the working directory and the date. The only cache marker sat at the end of that block. Because the environment part changed between jobs, the shared instructions were never cached on their own. Logging that started on September 14 showed the first request of each session reading from the cache only 14 to 26% of the time.
The fix, shipped September 16, was almost dull. The team added a marker at the end of every agent prompt and used a plugin hook to split the block there, so the shared half (11,000 to 21,000 tokens) got its own cache breakpoint. They also moved anything repository-specific out of that shared half. The list of available skills was switched off, and tool descriptions are no longer allowed to change between jobs.
First-request cache reads jumped to 91 to 99.5% of sessions. Together with a related change to the standards reviewer, cost per review fell from $2.47 to $2.02.
No new model. No new architecture. Just a prompt whose first 11,000 tokens finally stayed the same.
Fix two: stop paying for calls nobody needed
The next round of savings came from work the agents were doing for no one.
Tools an agent could see but never use. Specialist reviewers could see the tool that posts the final review comment, a job only the coordinator is allowed to do. In 57 to 76% of sessions they tried to call it anyway, got rejected by a server-side check, and spent another call recovering. Hiding that tool removed one wasted call per session and about 2,900 tokens of tool descriptions from every specialist request. Every tool definition you expose is text the model reads on every call, and a tempting one it can't use is worse than none.
Reviews of things that had not changed. About two thirds of jobs were second or later reviews of the same merge request. On those, the reviewer now skips specialists with nothing new to look at. On full re-reviews the AGENTS.md compliance check (AGENTS.md is a file of standing instructions for coding agents) now skips 56% of the time, performance 23%, documentation 13%.
A summary nobody read. After posting its review, OpenCode ran one more turn that re-read the whole conversation to write a summary that went nowhere. Stopping once the review is posted saved about $0.07 per job.
Jobs that ignored cancellation. This one is the most painful to read. GitLab's Kubernetes runner does not signal a job's script when the job is cancelled. In a sample of 446 cancelled jobs, 358 kept running until the review finished. Now each job checks its own status every 15 seconds and stops if it has been cancelled.
Slow agents treated as broken providers. A reviewer that hit its time limit used to be retried as if the API had failed, with the same limit, which mostly bought a second timeout. Handling the two cases separately, along with longer limits and lower effort, cut security reviewer timeouts from 1.8% of runs to almost none.
None of these fixes needs a research team. Each one needs someone to look at the logs and ask, "Why did this call happen?"
Fix three: the right model at the right effort
The biggest share of the savings came from model and effort choices, about $1.06 per review against about $0.65 from code changes, by the post's own breakdown. ("Effort" is the setting that controls how long a reasoning model thinks before answering. Higher effort usually means more tokens and more calls.)
Two decisions did most of the work. On October 3 the team split the specialists 50/50 between Sonnet 5 and Sonnet 5.5. After about two and a half days, Sonnet 5.5 was 62% cheaper per run for code quality, 58% for performance and 47% for security, mostly because it used far fewer tokens. Everything moved to 5.5 on October 5.
Effort mattered as much as the model. The code quality reviewer averaged 16.6 model calls per run in August. On Sonnet 5.5 at medium effort it averages 1.7, and more than half of runs finish in a single call.
That looks like a clean win. It isn't, and Cloudflare says so.
The part most cost posts skip: what got worse
Cutting cost is easy if you are willing to find fewer bugs. The honest test is whether the reviewer still catches what matters, and Cloudflare measured that two ways.
First, it checked whether authors acted on findings by comparing the reviewed commit with the author's next push. A serious finding counted as acted on if the lines it pointed at changed. Code quality's serious findings went from 34% acted on to 59%.
Second, two models from different providers judged 657 findings without knowing which period they came from, with a third model breaking ties. Important findings per review held roughly steady (0.28 before, 0.30 after), and findings rated more severe than they deserved dropped 70%. In plain terms, less crying wolf.
Then the bad news. The performance reviewer at medium effort lost about 64% of its important findings per review. Security's drop, about a quarter, was not statistically significant. And when the team ran code quality at both medium and high effort, high cost 61% more per run but posted 58% more critical and warning findings, so code quality is moving back to high. Security and performance at high effort are next on the test list.
This is the insight worth keeping. Price per token is the number on the pricing page. Cost per finished, useful review is the number that matters, and you can't see it without a quality measure next to the cost chart. A team that only watched the dollar line would have shipped a cheaper reviewer that misses most performance problems.
Put this into practice
You do not need Cloudflare's scale to run the same checks. Here is the order I would do them in, cheapest first.
1. Log your cache numbers per request. On Anthropic's Messages API, every response's usage object reports cache_read_input_tokens (read from cache), cache_creation_input_tokens (written to cache) and input_tokens (neither). Print them for the first request of each session, the way Cloudflare started doing on September 14:
response = client.messages.create(...)
u = response.usage
print(u.cache_read_input_tokens, u.cache_creation_input_tokens, u.input_tokens)
If first requests show mostly cache_creation_input_tokens and almost no reads, you are paying to write the same cache over and over.
2. Put a breakpoint after the shared part. Anthropic builds the cacheable prefix in a fixed order (tools, then system, then messages) and allows up to four cache_control breakpoints. Split your system prompt into a shared block and a per-job block, and mark the shared one:
system=[
{"type": "text", "text": SHARED_RULES,
"cache_control": {"type": "ephemeral"}},
{"type": "text", "text": per_job_context},
]
Then hunt for anything that sneaks variation into the shared part: dates, file paths, a skill list that differs per repo, tool descriptions generated on the fly.
3. Count rejected tool calls. Grep your traces (the step-by-step logs of every model and tool call) for tool calls that fail permission checks. Each one is a tool the agent should not have seen.
4. Make every job obey cancellation, and stop at the deliverable. Check status on a timer if your runner doesn't send a signal, and end the loop when the final output is posted.
5. Test the model and the effort side by side, and score quality alongside cost. Send half your jobs to each option for a few days, the way Cloudflare did, and track one quality signal next to cost per job. "Did the author change the flagged lines?" is cheap to compute from git and hard to fool.
Expect step 2 to show up in your bill within a day if your prefix was broken. Expect step 5 to take a week before you trust it.
Honest limitations
Cloudflare's numbers are Cloudflare's numbers. The post says outright that "this isn't a statistically sound controlled experiment": each step compares weekday hours before and after a change, several changes landed close together, and the newest quality window is a single day with 35 to 66 findings per group.
The cache math is provider-specific. The multipliers above are Anthropic's. Other providers cache differently, and some do it automatically with their own rules, so check your provider's docs before assuming the same savings.
Open source only goes so far here. The OpenCode agent is MIT-licensed, but the Claude models behind it are a paid, closed API, so copying the setup means paying the same kind of bill.
A few of the post's own figures don't line up perfectly. The starting point appears as both $2.43 and $2.44, and the $1.06 and $0.65 parts add to slightly more than the stated total. None of that changes the direction, but treat the exact splits as approximate.
And the savings have a ceiling. Once your prefix caches cleanly and your agents stop doing pointless work, the remaining cost is the actual thinking. That is the part you should be paying for.
Where to start
Pick one agent you run every day. Pull the usage numbers for the first request of its last 50 sessions, and look at the cache read column.
If it is near zero, you have found your first fix, and it probably takes an afternoon. If it is already high, go to the traces and count the calls that failed, repeated or ran after the job was done. Before you switch to a cheaper model or a lower effort, decide what "still good enough" means and write down how you will measure it.
The cheapest review is the one that still catches the bug.
Sources: Cloudflare, "Cutting our inference bill by 68% by being obsessive about optimization" (October 19, 2026); Anthropic prompt caching documentation; OpenCode on GitHub. All figures are Cloudflare's own measurements as published on October 19, 2026.