Here is how most solo builders find out their app is down: a user emails. And for every user who emails, several more just left — tried the page, got an error, closed the tab, formed an opinion.
The email is the worst monitoring system in the world, and it is the default one. It has unbounded delay, terrible coverage, and it only fires after the damage is done. Replacing it takes one evening and, at the scale of a new product, usually zero dollars.
Why AI-built apps break quietly
Any app can go down. AI-built apps have a specific talent for breaking silently, for reasons built into how they get made:
- You did not write the error handling. Agents love a wrapper. Code that catches an exception, logs nothing useful, and returns an empty list "handles" the error in the sense that nothing crashes — and hides it in every sense that matters. A page that quietly renders nothing looks, from the outside, like a page with no data.
- The failure lives in the glue. An AI-built app is typically a braid of managed services — database, auth, payments, email, a model API. Most real incidents are not "the server crashed"; they are one strand failing: an expired key, an exhausted quota, a provider having a bad hour. The app is "up." The feature is dead.
- Nobody has the map. When you hand-build an app you accumulate a mental model of what logs where and what fails how. When an agent builds it, that model was never in your head to begin with. Monitoring is how you buy the map back.
The fix is three layers, in order of effort.
Layer 1: an outside pulse
An uptime check is a service, outside your infrastructure, that requests a URL every minute and alerts you when the answer stops being 200. Several established monitoring services offer this free for a small number of URLs, and setup is ten minutes.
The one decision that matters is which URL. A homepage can render happily from cache while everything behind it is on fire. Have the agent add a health endpoint — /api/health — that does a trivial read from the database and touches whatever service your core feature cannot live without, returning an error status if either fails. Point the uptime check there. Now "up" means the app works, not the server answers.
That single check converts the unbounded delay of user emails into a bounded one: you know within about a minute, whether or not anyone was watching.
Layer 2: error tracking
The pulse tells you the app died. Error tracking tells you it is limping — the exceptions users hit that never take the whole site down.
An error-tracking service (Sentry is the common default, and its free tier is enough at this stage; several alternatives work the same way) collects every unhandled exception from your server and your users' browsers, with a stack trace, the URL, and the browser attached. The agent can wire the SDK into your framework in one session.
Two configuration choices do most of the work:
- Alert on new error types, not error counts. A hundred repeats of a known, tolerated error is Tuesday. One error you have never seen before, an hour after a deploy, is signal. "Notify me on first occurrence of a new issue" is the setting that catches it.
- Hunt the swallowed errors. This layer only sees exceptions that escape. Remember the agent's quiet
catchblocks: have it audit the codebase for catches that neither rethrow nor report, and route them into the tracker. This audit regularly turns up failures that have been happening for weeks.
Layer 3: logs you can actually use
The first two layers tell you that something broke. Logs are how you find out why, and the time to look at them is before the incident:
- Know where each service's logs live. Your host, your database, your auth provider, your payment provider — each has its own log page. Spend ten minutes finding all of them and put the links in one file. During an incident, "where do I even look" is the most expensive question.
- Check the retention. Free tiers commonly keep logs for a day or a few. If you learn about a problem on Monday that started Friday, short retention means the evidence is already gone. Know your window; lengthen it if a paid tier is cheap, or ship important events somewhere durable.
- Log decisions, not noise. One line per meaningful event — signup, payment, the model call that powers your core feature — with an identifier you can search for. When a user says "it broke for me yesterday," you want their trail, not a wall of framework chatter.
The alert budget: two
Monitoring fails one more way: you wire everything, feel thorough, get thirty notifications in week one, and mute the channel in week two. An alert you have learned to ignore is worse than no alert — it spends your trust and gives nothing back.
So start with an alert budget of exactly two:
- The pulse fails — health check down. This one is allowed to interrupt you.
- A new error type appears — first occurrence only.
Everything else — traffic graphs, performance, the long tail of known errors — is a dashboard you glance at weekly, not a page. Earn your way to a third alert only when one specific failure has bitten you twice.
The fifteen-minute drill
Like a backup you have never restored, monitoring you have never seen fire is a hope, not a system. So break something on purpose — in your staging environment, not production:
- Point staging's database connection at a wrong host. Did the health endpoint go red? Did the alert reach the place you actually look?
- Throw a deliberate exception in one route. Did it show up in error tracking within a minute, with a stack trace you can read?
- Time both. That number — failure to phone-buzz — is your real detection time.
Fifteen minutes, and you have replaced "I assume I would find out" with a measured answer.
The agent's role
All three layers are prompt-sized:
- "Add
/api/health: do a minimal database read and a check on [core service]; return 500 with a reason field if either fails." - "Integrate error tracking with [service]. Then audit the codebase for catch blocks that swallow errors silently and route them into it."
- "Write MONITORING.md: links to every service's log page, retention windows, what each of the two alerts means, and what to check first when each fires."
Run the drill yourself. The wiring is delegable; knowing that the buzz reaches your pocket is not.
The receipt
One dated line in MONITORING.md: "Drill [date] — killed staging DB, alert received in [measured time]; deliberate exception visible in tracker with stack trace. Two alerts configured, both tested."
Your users were always going to be the last to know something broke. The whole job is making sure that, from now on, you are the first.