Read the bill before you read the code
What I check first when I inherit someone else's app.
If you can't explain how your app works in plain English, you're one bad night away from finding out.
I've spent 12 years taking over other people's production systems: banks, government, startups and, more recently, apps built mostly by AI. The tools keep changing. The first things I check don't.
Here's what surprises most founders. The code is usually the last thing I look at.
Start with people, not code
In my first hour on an inherited system, I don't change a line. I don't even open the repo. I ask for whatever documentation exists, then I talk to everyone who built or runs the thing and is still around.
I want three things from those conversations: what they think the system does, where it hurts, and what they'd fix first. Then I map that against the business. Revenue, continuity, security, compliance. A fintech lives under heavy regulation, but almost everyone else still has GDPR to answer to, and plenty need SOC 2.
There's no point reading code until you know which problem you're solving.
If you're a solo founder, that conversation is with yourself. Write down how your app works as if you were briefing a new hire. Every gap in that explanation goes on your risk list.
The founder who was suffering from success
One founder I worked with had done the hard part. He'd vibe-coded an app for a narrow niche that solved a pain people happily paid for. Customers poured in.
Then the business started losing money. His AWS bill was climbing faster than his revenue, and his AI agents were giving customers strange answers. He told me he thought he'd have to shut down. Growth was killing the business.
The cause only surfaced when he talked me through how he'd built it. Each customer was served by AI agents, but nothing kept one customer's information apart from another's. The more customers he signed, the more their data bled together. It looked like hallucination. It was customers' data mixing.
Why it was a rebuild, not a fix
I've seen plenty of bad systems over the years, including PHP apps that made my eyes water. But bad systems usually have a pattern: a codebase, version control, something. This had none. It was a rubber-banded bundle of Python scripts, some Perl and some shell scripts, each doing one job, all talking to each other and the databases over REST. No repository. No CI/CD. No tests.
Kept small, it would have held together. At his size, there was nothing to fix in place.
So we didn't switch it off and start again. Over about two months I built a replacement alongside the live system, then moved functions across one at a time. Each time a piece worked in the new system, I turned the old script off. When the last one went, the business had never gone dark.
I built it in Scala because that's where I'm fastest, not to lock him in. If I'm handing a system back to an owner, I'll pick a stack they can easily hire for, like TypeScript and React.
The new agents keep each customer's data separate. It still burns a fair amount in tokens, but costs now grow with customers instead of ahead of them. I still speak to that founder today.
If you're buying: you might be buying a second job
Plenty of small software businesses are profitable only because the founder is quietly working on them full time. Buy one of those and you haven't bought a business. You've bought a job.
So ask how many hours a week it takes to run, and what breaks if the founder disappears for a month. Then assume the answer is optimistic. Sellers say "about five hours a week" every time.
Don't rely on the answer. Ask for the evidence:
- 12 months of cloud bills. Look for spikes, and ask the seller to explain each one.
- Monitoring and error logs. When do errors happen, how often, and were the spikes fixed or just ignored? No logging at all tells you something too.
- The support inbox. Lots of tickets about the same problem that never got fixed is a red flag, especially if the seller didn't mention it.
- Commit history. Is there version control at all? How do changes reach production?
The one that tells me most is the cloud bill. I've seen sellers flatten costs across the year so the spikes disappear. When I ask what happened in a spiky month, the answer is often a shrug.
Spikes have causes. A Reddit post that sent traffic flooding in. Bots probing for weak spots. A DDoS. A seller who can't explain them doesn't fully understand their own system, and that means you inherit the surprise. Possibly at the same time next year.
The $5,000 lesson: deleting isn't fixing
One founder had a cloud bill that jumped for no obvious reason. It turned out he'd accidentally pushed his AWS credentials to GitHub. This was during the crypto boom, before GitHub had the guardrails it has now.
He noticed quickly and deleted them. What he didn't do was rotate the keys. Someone had already scraped them and was using his AWS account to mine cryptocurrency.
By the time he'd searched for what to do and rotated them, he'd run up roughly $5,000 in a few days. Honestly, he got off lightly. Attackers often spin up machines in every region at once.
Once a secret has been public, deleting it isn't the fix. Rotating it is. Git history, forks and scrapers already have it.
If your app was built with AI tools, check this now: keys pasted into prompts, keys sitting in frontend code, secrets committed "just for now". If you're not sure whether something leaked, rotate it anyway. It's far cheaper than finding out.
Read the bill before you read the code.
Why AI sounds so sure
AI coding tools are extremely good at sounding certain. If you've watched a few YouTube tutorials and written one Python script, that confidence is reassuring. It shouldn't be.
I use AI tools to write Scala, the language I know best. Once it gave me code that ran fine but was written like Java, with loops that would get slower and slower as the data grew. Fine in a demo. A bottleneck in production.
I asked whether this was the best way to write it. It said yes: it had looked at the common patterns and this was what everyone agreed on. It took three or four rounds of pushback before it admitted there were better options.
I only caught it because I already knew the answer. A founder without that background would have shipped it.
Asking the same AI to review its own work mostly gets you more confidence. What actually helps:
- Write the spec first. AI writes code fast, so the valuable, slow part is now deciding exactly what to build. Get that right before you generate anything new.
- Keep sessions small. Long sessions stuffed with context are where tools get confused.
- Use independent reviewers with different rules. One agent checks security, another performance, another tests, each starting fresh. They catch different things because none of them is defending work it wrote.
None of this makes an AI-built app bulletproof. It just shrinks the odds.
Three checks you can do this week
None of these needs you to read code.
- Rotate every key and password. Cloud, database, payments, AI provider. Include the ones you think you deleted.
- Become two customers. Create two test accounts. Log in as one and try to see the other's data, for example by changing an ID in the address bar. If you can, so can anyone.
- Explain your last 12 months of cloud bills out loud. Every spike. Whatever you can't explain is the first job on your list.
The one thing to remember
Your app's problems already exist. Find them yourself and they're cheap. Let your customers find them and they're not.
Robert Udah is principal engineer at Holdfast, which runs fixed-fee technical audits for founders and buyers of small software businesses. See what an audit covers or read a sample report. Follow Robert on Medium.