The email arrived Friday at 4:12 p.m., with a screenshot. "Is the portal supposed to look like this?" The portal was not supposed to look like that. The error page had been up since Tuesday morning, which meant three days of clients hitting the problem, drawing their own conclusions, and, this is the part that stings, not telling you.

Small apps don't fail loudly in your direction. They fail quietly in the client's direction. The fix is not an enterprise observability platform with a sales team. You can monitor small web applications cheap, effectively free, with four pieces: a health endpoint pinged by an uptime monitor, error tracking wired to somewhere you actually look, a heartbeat for scheduled jobs, and one public status page.

That stack covers about ninety-five percent of small-app failure modes until roughly three apps. Past that, you graduate to twenty or fifty dollars a month. Not two thousand.

The four things worth watching

Everything you'd want to know fits in four buckets. Uptime: is it up at all. Errors: is it throwing exceptions. Jobs: did the 2 a.m. sync actually run. Slowness: is it quietly dying, response times doubling week over week while nobody complains yet. Cover those four and you've covered the ways small apps actually die. Everything else (tracing, profiling, service maps) is a hobby until you have the traffic to justify it.

Slowness deserves the extra sentence because it's the sneakiest. Apps rarely fall over in one dramatic moment. The disk fills at two percent a week, the unindexed table grows, the p95 creeps from 300 milliseconds to two seconds, and users just quietly stop coming back. A weekly glance at response-time percentiles catches the disease while it's still cheap to cure.

The failure mode most teams miss is the silent kind. No errors, no crashes, just a form that takes eight seconds instead of one. Users don't complain; they leave. By the time someone notices the conversion rate drop, the app has been dying for a month.

The zero-dollar stack

Each piece has a free tier that is genuinely enough at small scale:

Where this sits in the wider kit is mapped in the FDE stack essentials. And when the app runs on a box under a desk in Topeka, health checks matter twice as much, for the reasons in the guide to Docker on client hardware: you can't just walk over and look at it.

One implementation detail worth stealing: make the health endpoint check the things the app actually needs. Database reachable, disk under ninety percent, the last sync less than a day old. A 200 that only proves the web server is alive tells you the lights are on while the kitchen burns.

One status page saves twenty emails

A public status page is the cheapest trust machine in software. Free tiers exist, setup is an hour, and it converts every "is it down for everyone?" into a link you send once. Clients check it instead of calling you, which is good for everyone, including the clients, who mostly wanted to know whether to wait or phone it in.

The side effect nobody mentions: it's an uptime track record at renewal time. Ninety-nine point nine percent, with receipts, is a much better slide than "it's been pretty reliable, honestly."

When something does break, post to the status page before the first client email arrives. Two sentences, what's affected and that you're on it, turn an outage into a demonstration of competence. Silence turns the same outage into a demonstration of something else.

Alerts that don't cry wolf

Alert fatigue kills monitoring faster than no monitoring. Three rules keep it alive. Alert on symptoms users feel, not on every 500; a burst of errors on a marketing page at 3 a.m. is noise, a failed checkout is a page. Require two consecutive failures before waking anyone, because networks hiccup. And give every alert exactly one human owner, because an alert everyone owns is an alert nobody reads.

Then hold a weekly ten-minute review. If an alert fired and the correct response was "yeah, it does that," fix it or delete it that day. The instinct to self-host everything for control and cost, the same one behind self-hosting LLMs for clients, has one exception: your monitor. It must be up when you're down, so let someone else's infrastructure watch yours.

When to start paying

The ladder is short. Stay at $0 until you have three apps or a customer's revenue depends on your uptime. Then spend twenty to fifty a month on longer retention, on-call rotation, and a status page on your own domain. That's also the point where a client starts asking for an SLA, which is a fun conversation to have with receipts and a miserable one to have without them.

What you never need at this scale is the platform whose pricing page says "contact sales." If a vendor wants a discovery call before quoting the price of watching a WordPress site and two internal tools, the price is not for you. Keep the whole bill boring, the same discipline as LLM cost control: spend on the signal, never on the dashboard jewelry.

Friday at 4:12 still happens; software fails. The difference is the alert now fires Tuesday at 9:07 a.m., you fix it before lunch, and Friday's email, when it comes, is about something you already knew. Which is the whole job, really.