I Let AI Agents Review and Merge PRs. Then Disaster Struck.

The features worked, but background jobs kept my serverless database awake. AI code review missed the operating assumption that made the design expensive.

Nothing crashed. The features worked. Which is what made it easy to miss.

Behind the scenes, my fitness app was keeping its serverless database running around the clock… burning through credits while barely anyone was using it.

Agents wrote the code. Other agents reviewed it. The code got merged. Nobody caught the assumption that the database should always be awake.

I found out when I checked the usage.

The app itself does quite a bit: AI food logging from photos and voice, body-fat estimation, workouts, step tracking through an API, and more. Exactly the kind of project where agents can help you build a lot, quickly.

And they did.

But they also built a collection of background jobs and polling loops that kept asking the database whether anything needed to happen.

Anything yet?

How about now?

Now?

A fitness app where the database was getting more exercise than the users.

The expensive assumption

I was using Neon, a serverless Postgres database. Given the app’s activity, I expected usage to stay comfortably within the free allowance.

Neon can suspend its compute when it’s inactive. But it needs a chance to become inactive. Frequent queries and connection requests can keep it awake and consuming compute. Neon documents this behavior.

The agents had designed around a different operating model: Postgres sitting there, running continuously, ready for another query.

With a database you’re already running around the clock, an occasional background check might be an acceptable tradeoff. With serverless compute, that same check can help turn “pay when you use it” into “pay because your app won’t shut up.”

Each piece looked reasonable in isolation. Check a job’s status. Refresh some data. Run a maintenance sweep.

Collectively, they defeated one of the reasons I’d chosen the infrastructure.

The code worked. The economics didn’t.

So much for independent review

This wasn’t a case where I pasted some generated code into production and hoped for the best.

Agents implemented features. Tested them. Reviewed PRs. Merged changes.

The workflow had review. It just didn’t catch the architectural mismatch.

A test could confirm that a workout saved correctly. A reviewer could confirm that a background job handled failures. Neither necessarily asked why that job needed to keep querying the database when there was nothing to do.

The missing question was simple:

What does this app cost when nobody is using it?

That’s an easy question to overlook when your definition of success is a working feature.

And if the implementation agent and the review agents share the same assumption, you can get several rounds of approval without anyone challenging it.

More reviewers. Same blind spot.

I had to change the design

Once I noticed the Neon usage, I had to redirect the implementation around a serverless operating model.

The redesign focused on a few things:

  • Schedule work for when it’s needed, rather than repeatedly checking whether it’s needed.
  • Pause database-backed browser reads when the page is hidden or the user is idle.
  • Group recurring maintenance into shared windows instead of spreading wakeups across the hour.
  • Check whether the app is alive without querying the database just to prove it.

The goal wasn’t to eliminate every poll or make every task instant. It was to decide which work justified waking a paid resource and which work could wait.

What I want agents to prove now

I still want agents writing code, testing features, reviewing PRs, and merging changes. I’m not going back to doing all of that manually because they missed something.

But I want the operating assumptions reviewed as explicitly as the code.

What keeps running after I close the app?

Which jobs wake a paid service?

Does this task really need to run every minute, or would an hour be fine?

What happens when there are zero users? What happens when there are ten thousand?

How will we notice when actual usage stops matching the design?

Those belong in the requirements and verification process. Otherwise, “done” can mean the feature works beautifully while something expensive runs forever in the background.

This is why engineers still have an important role, even when agents write, test, review, and merge the code.

Someone has to understand the whole system: what we’re building, where it runs, what it costs, and whether the design fits those choices.

Operator dashboards are critical. Usage, costs, background activity, errors… that’s how you see whether the system is behaving the way you intended. My features looked fine. My database usage told a different story.

The agents could implement the fix once I identified the problem and changed the design direction. But I had to notice it first.

Let agents handle more of the implementation. As engineers, we still need to pay close attention to the bigger picture.

The PR is a small part of the system. We’re responsible for the rest of it too.

Written by Adib Kadir. Personal notes on software, AI, and building things.

About the author